mirror of
https://github.com/appleboy/drone-jenkins.git
synced 2026-06-04 18:23:57 +08:00
feat: add remote trigger token support for Jenkins job execution
- Add support for passing a remote trigger token to Jenkins jobs - Update the Jenkins constructor to accept a token parameter - Ensure the token is included as a query parameter when triggering jobs - Improve error reporting by including response body in error messages - Remove unnecessary logging and refactor build parameter logic - Update tests to use the new Jenkins constructor and token handling - Add CLI option for specifying a remote trigger token - Extend plugin configuration to support remote token injection Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
+30
-12
@@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -23,12 +22,13 @@ type (
|
|||||||
Jenkins struct {
|
Jenkins struct {
|
||||||
Auth *Auth
|
Auth *Auth
|
||||||
BaseURL string
|
BaseURL string
|
||||||
|
Token string // Remote trigger token
|
||||||
Client *http.Client
|
Client *http.Client
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewJenkins is initial Jenkins object
|
// NewJenkins is initial Jenkins object
|
||||||
func NewJenkins(auth *Auth, url string, insecure bool) *Jenkins {
|
func NewJenkins(auth *Auth, url string, token string, insecure bool) *Jenkins {
|
||||||
url = strings.TrimRight(url, "/")
|
url = strings.TrimRight(url, "/")
|
||||||
|
|
||||||
client := http.DefaultClient
|
client := http.DefaultClient
|
||||||
@@ -44,6 +44,7 @@ func NewJenkins(auth *Auth, url string, insecure bool) *Jenkins {
|
|||||||
return &Jenkins{
|
return &Jenkins{
|
||||||
Auth: auth,
|
Auth: auth,
|
||||||
BaseURL: url,
|
BaseURL: url,
|
||||||
|
Token: token,
|
||||||
Client: client,
|
Client: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,12 +71,12 @@ func (jenkins *Jenkins) sendRequest(req *http.Request) (*http.Response, error) {
|
|||||||
func (jenkins *Jenkins) parseResponse(resp *http.Response, body interface{}) (err error) {
|
func (jenkins *Jenkins) parseResponse(resp *http.Response, body interface{}) (err error) {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if body == nil {
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := io.ReadAll(resp.Body)
|
if body == nil {
|
||||||
if err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +85,7 @@ func (jenkins *Jenkins) parseResponse(resp *http.Response, body interface{}) (er
|
|||||||
|
|
||||||
func (jenkins *Jenkins) post(path string, params url.Values, body interface{}) (err error) {
|
func (jenkins *Jenkins) post(path string, params url.Values, body interface{}) (err error) {
|
||||||
requestURL := jenkins.buildURL(path, params)
|
requestURL := jenkins.buildURL(path, params)
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(context.Background(), "POST", requestURL, nil)
|
req, err := http.NewRequestWithContext(context.Background(), "POST", requestURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -95,7 +97,7 @@ func (jenkins *Jenkins) post(path string, params url.Values, body interface{}) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {
|
||||||
return fmt.Errorf("unexpected response code: %d", resp.StatusCode)
|
return fmt.Errorf("unexpected response code: %d, body: %s", resp.StatusCode, string(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
return jenkins.parseResponse(resp, body)
|
return jenkins.parseResponse(resp, body)
|
||||||
@@ -119,14 +121,30 @@ func (jenkins *Jenkins) parseJobPath(job string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (jenkins *Jenkins) trigger(job string, params url.Values) error {
|
func (jenkins *Jenkins) trigger(job string, params url.Values) error {
|
||||||
var urlPath string
|
// Add remote trigger token to params
|
||||||
if len(params) == 0 {
|
if jenkins.Token != "" {
|
||||||
urlPath = jenkins.parseJobPath(job) + "/build"
|
if params == nil {
|
||||||
} else {
|
params = url.Values{}
|
||||||
urlPath = jenkins.parseJobPath(job) + "/buildWithParameters"
|
}
|
||||||
|
params.Set("token", jenkins.Token)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println(urlPath)
|
var urlPath string
|
||||||
|
// Check if params contains build parameters (excluding 'token')
|
||||||
|
hasBuildParams := false
|
||||||
|
for key := range params {
|
||||||
|
if key != "token" {
|
||||||
|
hasBuildParams = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasBuildParams {
|
||||||
|
urlPath = jenkins.parseJobPath(job) + "/buildWithParameters"
|
||||||
|
} else {
|
||||||
|
urlPath = jenkins.parseJobPath(job) + "/build"
|
||||||
|
}
|
||||||
|
|
||||||
|
// All params (including token) are passed as query parameters
|
||||||
return jenkins.post(urlPath, params, nil)
|
return jenkins.post(urlPath, params, nil)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -12,7 +12,7 @@ func TestParseJobPath(t *testing.T) {
|
|||||||
Username: "appleboy",
|
Username: "appleboy",
|
||||||
Token: "1234",
|
Token: "1234",
|
||||||
}
|
}
|
||||||
jenkins := NewJenkins(auth, "http://example.com", false)
|
jenkins := NewJenkins(auth, "http://example.com", "", false)
|
||||||
|
|
||||||
assert.Equal(t, "/job/foo", jenkins.parseJobPath("/foo/"))
|
assert.Equal(t, "/job/foo", jenkins.parseJobPath("/foo/"))
|
||||||
assert.Equal(t, "/job/foo", jenkins.parseJobPath("foo/"))
|
assert.Equal(t, "/job/foo", jenkins.parseJobPath("foo/"))
|
||||||
@@ -25,7 +25,7 @@ func TestUnSupportProtocol(t *testing.T) {
|
|||||||
Username: "foo",
|
Username: "foo",
|
||||||
Token: "bar",
|
Token: "bar",
|
||||||
}
|
}
|
||||||
jenkins := NewJenkins(auth, "example.com", false)
|
jenkins := NewJenkins(auth, "example.com", "", false)
|
||||||
|
|
||||||
err := jenkins.trigger("drone-jenkins", nil)
|
err := jenkins.trigger("drone-jenkins", nil)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
@@ -36,8 +36,8 @@ func TestTriggerBuild(t *testing.T) {
|
|||||||
Username: "foo",
|
Username: "foo",
|
||||||
Token: "bar",
|
Token: "bar",
|
||||||
}
|
}
|
||||||
jenkins := NewJenkins(auth, "http://example.com", false)
|
jenkins := NewJenkins(auth, "http://example.com", "remote-token", false)
|
||||||
|
|
||||||
err := jenkins.trigger("drone-jenkins", url.Values{"token": []string{"bar"}})
|
err := jenkins.trigger("drone-jenkins", url.Values{"param": []string{"value"}})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,9 +48,14 @@ func main() {
|
|||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "token",
|
Name: "token",
|
||||||
Aliases: []string{"t"},
|
Aliases: []string{"t"},
|
||||||
Usage: "jenkins token",
|
Usage: "jenkins API token for authentication",
|
||||||
EnvVars: []string{"PLUGIN_TOKEN", "JENKINS_TOKEN", "INPUT_TOKEN"},
|
EnvVars: []string{"PLUGIN_TOKEN", "JENKINS_TOKEN", "INPUT_TOKEN"},
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "remote-token",
|
||||||
|
Usage: "jenkins remote trigger token",
|
||||||
|
EnvVars: []string{"PLUGIN_REMOTE_TOKEN", "JENKINS_REMOTE_TOKEN", "INPUT_REMOTE_TOKEN"},
|
||||||
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "job",
|
Name: "job",
|
||||||
Aliases: []string{"j"},
|
Aliases: []string{"j"},
|
||||||
@@ -112,12 +117,13 @@ REPOSITORY:
|
|||||||
|
|
||||||
func run(c *cli.Context) error {
|
func run(c *cli.Context) error {
|
||||||
plugin := Plugin{
|
plugin := Plugin{
|
||||||
BaseURL: c.String("host"),
|
BaseURL: c.String("host"),
|
||||||
Username: c.String("user"),
|
Username: c.String("user"),
|
||||||
Token: c.String("token"),
|
Token: c.String("token"),
|
||||||
Job: c.StringSlice("job"),
|
RemoteToken: c.String("remote-token"),
|
||||||
Insecure: c.Bool("insecure"),
|
Job: c.StringSlice("job"),
|
||||||
Parameters: c.StringSlice("parameters"),
|
Insecure: c.Bool("insecure"),
|
||||||
|
Parameters: c.StringSlice("parameters"),
|
||||||
}
|
}
|
||||||
|
|
||||||
return plugin.Exec()
|
return plugin.Exec()
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ import (
|
|||||||
type (
|
type (
|
||||||
// Plugin values.
|
// Plugin values.
|
||||||
Plugin struct {
|
Plugin struct {
|
||||||
BaseURL string
|
BaseURL string
|
||||||
Username string
|
Username string
|
||||||
Token string
|
Token string
|
||||||
Job []string
|
RemoteToken string
|
||||||
Insecure bool
|
Job []string
|
||||||
Parameters []string
|
Insecure bool
|
||||||
|
Parameters []string
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ func (p Plugin) Exec() error {
|
|||||||
Token: p.Token,
|
Token: p.Token,
|
||||||
}
|
}
|
||||||
|
|
||||||
jenkins := NewJenkins(auth, p.BaseURL, p.Insecure)
|
jenkins := NewJenkins(auth, p.BaseURL, p.RemoteToken, p.Insecure)
|
||||||
|
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
for _, v := range p.Parameters {
|
for _, v := range p.Parameters {
|
||||||
|
|||||||
Reference in New Issue
Block a user