1 Commits

Author SHA1 Message Date
Thomas Boerger 69b094965b Refactoring and new plugin lib
This commit is doing a general refactoring of the current code base and
it also integrates the new plugin lib.
2019-09-16 23:22:59 +02:00
9 changed files with 340 additions and 258 deletions
+28
View File
@@ -45,6 +45,34 @@ def testing():
} }
] ]
}, },
{
'name': 'lint',
'image': 'golang:1.12',
'pull': 'always',
'commands': [
'go run golang.org/x/lint/golint -set_exit_status ./...'
],
'volumes': [
{
'name': 'gopath',
'path': '/go'
}
]
},
{
'name': 'staticcheck',
'image': 'golang:1.12',
'pull': 'always',
'commands': [
'go run honnef.co/go/tools/cmd/staticcheck ./...'
],
'volumes': [
{
'name': 'gopath',
'path': '/go'
}
]
},
{ {
'name': 'test', 'name': 'test',
'image': 'golang:1.12', 'image': 'golang:1.12',
+1 -1
View File
@@ -1,5 +1,5 @@
--- ---
{"kind": "pipeline", "type": "docker", "name": "testing", "platform": {"os": "linux", "arch": "amd64"}, "steps": [{"name": "vet", "image": "golang:1.12", "pull": "always", "commands": ["go vet ./..."], "volumes": [{"name": "gopath", "path": "/go"}]}, {"name": "test", "image": "golang:1.12", "pull": "always", "commands": ["go test -cover ./..."], "volumes": [{"name": "gopath", "path": "/go"}]}], "volumes": [{"name": "gopath", "temp": {}}], "trigger": {"ref": ["refs/heads/master", "refs/tags/**", "refs/pull/**"]}} {"kind": "pipeline", "type": "docker", "name": "testing", "platform": {"os": "linux", "arch": "amd64"}, "steps": [{"name": "vet", "image": "golang:1.12", "pull": "always", "commands": ["go vet ./..."], "volumes": [{"name": "gopath", "path": "/go"}]}, {"name": "lint", "image": "golang:1.12", "pull": "always", "commands": ["go run golang.org/x/lint/golint -set_exit_status ./..."], "volumes": [{"name": "gopath", "path": "/go"}]}, {"name": "staticcheck", "image": "golang:1.12", "pull": "always", "commands": ["go run honnef.co/go/tools/cmd/staticcheck ./..."], "volumes": [{"name": "gopath", "path": "/go"}]}, {"name": "test", "image": "golang:1.12", "pull": "always", "commands": ["go test -cover ./..."], "volumes": [{"name": "gopath", "path": "/go"}]}], "volumes": [{"name": "gopath", "temp": {}}], "trigger": {"ref": ["refs/heads/master", "refs/tags/**", "refs/pull/**"]}}
--- ---
{"kind": "pipeline", "type": "docker", "name": "linux-amd64", "platform": {"os": "linux", "arch": "amd64"}, "steps": [{"name": "build-push", "image": "golang:1.12", "pull": "always", "environment": {"CGO_ENABLED": "0"}, "commands": ["go build -v -ldflags \"-X main.version=${DRONE_COMMIT_SHA:0:8}\" -a -tags netgo -o release/linux/amd64/drone-webhook"], "when": {"event": {"exclude": ["tag"]}}}, {"name": "build-tag", "image": "golang:1.12", "pull": "always", "environment": {"CGO_ENABLED": "0"}, "commands": ["go build -v -ldflags \"-X main.version=${DRONE_TAG##v}\" -a -tags netgo -o release/linux/amd64/drone-webhook"], "when": {"event": ["tag"]}}, {"name": "executable", "image": "golang:1.12", "pull": "always", "commands": ["./release/linux/amd64/drone-webhook --help"]}, {"name": "dryrun", "image": "plugins/docker", "pull": "always", "settings": {"dry_run": true, "tags": "linux-amd64", "dockerfile": "docker/Dockerfile.linux.amd64", "repo": "plugins/webhook", "username": {"from_secret": "docker_username"}, "password": {"from_secret": "docker_password"}}, "when": {"event": ["pull_request"]}}, {"name": "publish", "image": "plugins/docker", "pull": "always", "settings": {"auto_tag": true, "auto_tag_suffix": "linux-amd64", "dockerfile": "docker/Dockerfile.linux.amd64", "repo": "plugins/webhook", "username": {"from_secret": "docker_username"}, "password": {"from_secret": "docker_password"}}, "when": {"event": {"exclude": ["pull_request"]}}}], "depends_on": ["testing"], "trigger": {"ref": ["refs/heads/master", "refs/tags/**", "refs/pull/**"]}} {"kind": "pipeline", "type": "docker", "name": "linux-amd64", "platform": {"os": "linux", "arch": "amd64"}, "steps": [{"name": "build-push", "image": "golang:1.12", "pull": "always", "environment": {"CGO_ENABLED": "0"}, "commands": ["go build -v -ldflags \"-X main.version=${DRONE_COMMIT_SHA:0:8}\" -a -tags netgo -o release/linux/amd64/drone-webhook"], "when": {"event": {"exclude": ["tag"]}}}, {"name": "build-tag", "image": "golang:1.12", "pull": "always", "environment": {"CGO_ENABLED": "0"}, "commands": ["go build -v -ldflags \"-X main.version=${DRONE_TAG##v}\" -a -tags netgo -o release/linux/amd64/drone-webhook"], "when": {"event": ["tag"]}}, {"name": "executable", "image": "golang:1.12", "pull": "always", "commands": ["./release/linux/amd64/drone-webhook --help"]}, {"name": "dryrun", "image": "plugins/docker", "pull": "always", "settings": {"dry_run": true, "tags": "linux-amd64", "dockerfile": "docker/Dockerfile.linux.amd64", "repo": "plugins/webhook", "username": {"from_secret": "docker_username"}, "password": {"from_secret": "docker_password"}}, "when": {"event": ["pull_request"]}}, {"name": "publish", "image": "plugins/docker", "pull": "always", "settings": {"auto_tag": true, "auto_tag_suffix": "linux-amd64", "dockerfile": "docker/Dockerfile.linux.amd64", "repo": "plugins/webhook", "username": {"from_secret": "docker_username"}, "password": {"from_secret": "docker_password"}}, "when": {"event": {"exclude": ["pull_request"]}}}], "depends_on": ["testing"], "trigger": {"ref": ["refs/heads/master", "refs/tags/**", "refs/pull/**"]}}
--- ---
-16
View File
@@ -1,16 +0,0 @@
package main
const respFormat = `Webhook %d
URL: %s
RESPONSE STATUS: %s
RESPONSE BODY: %s
`
const debugFormat = `Webhook %d
URL: %s
METHOD: %s
HEADERS: %s
REQUEST BODY: %s
RESPONSE STATUS: %s
RESPONSE BODY: %s
`
+6 -2
View File
@@ -3,10 +3,14 @@ module github.com/drone-plugins/drone-webhook
require ( require (
bou.ke/monkey v1.0.1 // indirect bou.ke/monkey v1.0.1 // indirect
github.com/aymerick/raymond v2.0.2+incompatible // indirect github.com/aymerick/raymond v2.0.2+incompatible // indirect
github.com/drone-plugins/drone-plugin-lib v0.0.0-20190916204527-6b33d765aca4
github.com/drone/drone-template-lib v0.0.0-20181004051823-4019baa6c594 github.com/drone/drone-template-lib v0.0.0-20181004051823-4019baa6c594
github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1
github.com/pkg/errors v0.8.1 // indirect github.com/pkg/errors v0.8.1 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/stretchr/testify v1.3.0 // indirect github.com/stretchr/testify v1.3.0 // indirect
github.com/tkuchiki/faketime v0.1.1 // indirect github.com/tkuchiki/faketime v0.1.1 // indirect
github.com/urfave/cli v1.20.0 github.com/urfave/cli v1.21.0
gopkg.in/yaml.v2 v2.2.2 // indirect golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac // indirect
honnef.co/go/tools v0.0.1-2019.2.3 // indirect
) )
+41
View File
@@ -1,23 +1,64 @@
bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U= bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U=
bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0= github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0=
github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/drone-plugins/drone-plugin-lib v0.0.0-20190905223702-0352df680f17 h1:x441B4/1FGRHg92xWAithZQUhsUysY+hZca3Wo6fuTQ=
github.com/drone-plugins/drone-plugin-lib v0.0.0-20190916204527-6b33d765aca4 h1:CxEkk5WIstHlmg+locKHxTnJ/rzk08P3FE5W1hFCEBk=
github.com/drone-plugins/drone-plugin-lib v0.0.0-20190916204527-6b33d765aca4/go.mod h1:Jd/3DVk8GYEuFXhOZ2UZ3D7iwoXIfZXdIQ1BaBpBBls=
github.com/drone/drone-template-lib v0.0.0-20181004051823-4019baa6c594 h1:zPRVfiHpXeGt1XGpK2TQcaj2lRydiGdVz1AoHkaC554= github.com/drone/drone-template-lib v0.0.0-20181004051823-4019baa6c594 h1:zPRVfiHpXeGt1XGpK2TQcaj2lRydiGdVz1AoHkaC554=
github.com/drone/drone-template-lib v0.0.0-20181004051823-4019baa6c594/go.mod h1:u34woe41m58Whrf21iH6z/xLOIRM3650LhWAyUc7Oik= github.com/drone/drone-template-lib v0.0.0-20181004051823-4019baa6c594/go.mod h1:u34woe41m58Whrf21iH6z/xLOIRM3650LhWAyUc7Oik=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1 h1:9Xm8CKtMZIXgcopfdWk/qZ1rt0HjMgfMR9nxxSeK6vk=
github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1/go.mod h1:zuHl3Hh+e9P6gmBPvcqR1HjkaWHC/csgyskg6IaFKFo=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tkuchiki/faketime v0.1.1 h1:UZjBlktFAi23wo+jWuHuNoHUpLnB0j/5B62bl5nCPls= github.com/tkuchiki/faketime v0.1.1 h1:UZjBlktFAi23wo+jWuHuNoHUpLnB0j/5B62bl5nCPls=
github.com/tkuchiki/faketime v0.1.1/go.mod h1:RXY/TXAwGGL36IKDjrHFMcjpUrEiyWSEtLhFPw3UWF0= github.com/tkuchiki/faketime v0.1.1/go.mod h1:RXY/TXAwGGL36IKDjrHFMcjpUrEiyWSEtLhFPw3UWF0=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.21.0 h1:wYSSj06510qPIzGSua9ZqsncMmWE3Zr55KBERygyrxE=
github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFztO+dMTM49DNAaWfO5OeY=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+12
View File
@@ -0,0 +1,12 @@
package main
// intInSlice checks if int is in slice of ints
func intInSlice(s []int, e int) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
+136 -132
View File
@@ -1,9 +1,10 @@
package main package main
import ( import (
"log"
"os" "os"
"github.com/drone-plugins/drone-plugin-lib/pkg/urfave"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@@ -11,6 +12,68 @@ var (
version = "unknown" version = "unknown"
) )
const (
// MethodFlag defines the method flag name
MethodFlag = "method"
// MethodEnvVar defines the method env var
MethodEnvVar = "PLUGIN_METHOD"
// UsernameFlag defines the username flag name
UsernameFlag = "username"
// UsernameEnvVar defines the username env var
UsernameEnvVar = "PLUGIN_USERNAME,WEBHOOK_USERNAME"
// PasswordFlag defines the password flag name
PasswordFlag = "password"
// PasswordEnvVar defines the password env var
PasswordEnvVar = "PLUGIN_PASSWORD,WEBHOOK_PASSWORD"
// ContentTypeFlag defines the content type flag name
ContentTypeFlag = "content-type"
// ContentTypeEnvVar defines the content type env var
ContentTypeEnvVar = "PLUGIN_CONTENT_TYPE"
// TemplateFlag defines the template flag name
TemplateFlag = "template"
// TemplateEnvVar defines the template env var
TemplateEnvVar = "PLUGIN_TEMPLATE"
// HeadersFlag defines the headers flag name
HeadersFlag = "headers"
// HeadersEnvVar defines the headers env var
HeadersEnvVar = "PLUGIN_HEADERS"
// URLsFlag defines the urls flag name
URLsFlag = "urls"
// URLsEnvVar defines the urls env var
URLsEnvVar = "PLUGIN_URLS,PLUGIN_URL,WEBHOOK_URLS,WEBHOOK_URL"
// ValidResponseCodesFlag defines the valid response codes flag name
ValidResponseCodesFlag = "valid-response-codes"
// ValidResponseCodesEnvVar defines the valid response codes env var
ValidResponseCodesEnvVar = "PLUGIN_VALID_RESPONSE_CODES"
// DebugFlag defines the debug flag name
DebugFlag = "debug"
// DebugEnvVar defines the debug env var
DebugEnvVar = "PLUGIN_DEBUG"
// SkipVerifyFlag defines the skip verify flag name
SkipVerifyFlag = "skip-verify"
// SkipVerifyEnvVar defines the skip verify env var
SkipVerifyEnvVar = "PLUGIN_SKIP_VERIFY"
)
func main() { func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "webhook plugin" app.Name = "webhook plugin"
@@ -19,179 +82,120 @@ func main() {
app.Version = version app.Version = version
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "method", Name: MethodFlag,
Usage: "webhook method", Usage: "webhook method",
EnvVar: "PLUGIN_METHOD", EnvVar: MethodEnvVar,
Value: "POST", Value: "POST",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "username", Name: UsernameFlag,
Usage: "username for basic auth", Usage: "username for basic auth",
EnvVar: "PLUGIN_USERNAME,WEBHOOK_USERNAME", EnvVar: UsernameEnvVar,
}, },
cli.StringFlag{ cli.StringFlag{
Name: "password", Name: PasswordFlag,
Usage: "password for basic auth", Usage: "password for basic auth",
EnvVar: "PLUGIN_PASSWORD,WEBHOOK_PASSWORD", EnvVar: PasswordEnvVar,
}, },
cli.StringFlag{ cli.StringFlag{
Name: "content-type", Name: ContentTypeFlag,
Usage: "content type", Usage: "content type",
EnvVar: "PLUGIN_CONTENT_TYPE", EnvVar: ContentTypeEnvVar,
Value: "application/json", Value: "application/json",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "template", Name: TemplateFlag,
Usage: "custom template for webhook", Usage: "custom template for webhook",
EnvVar: "PLUGIN_TEMPLATE", EnvVar: TemplateEnvVar,
}, },
cli.StringSliceFlag{ cli.StringSliceFlag{
Name: "headers", Name: HeadersFlag,
Usage: "custom headers key map", Usage: "custom headers key map",
EnvVar: "PLUGIN_HEADERS", EnvVar: HeadersEnvVar,
}, },
cli.StringSliceFlag{ cli.StringSliceFlag{
Name: "urls", Name: URLsFlag,
Usage: "list of urls to perform the action on", Usage: "list of urls to perform the action on",
EnvVar: "PLUGIN_URLS,WEBHOOK_URLS", EnvVar: URLsEnvVar,
}, },
cli.IntSliceFlag{ cli.IntSliceFlag{
Name: "valid-response-codes", Name: ValidResponseCodesFlag,
Usage: "list of valid http response codes", Usage: "list of valid http response codes",
EnvVar: "PLUGIN_VALID_RESPONSE_CODES", EnvVar: ValidResponseCodesEnvVar,
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "debug", Name: DebugFlag,
Usage: "enable debug information", Usage: "enable debug information",
EnvVar: "PLUGIN_DEBUG", EnvVar: DebugEnvVar,
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "skip-verify", Name: SkipVerifyFlag,
Usage: "skip ssl verification", Usage: "skip ssl verification",
EnvVar: "PLUGIN_SKIP_VERIFY", EnvVar: SkipVerifyEnvVar,
},
cli.StringFlag{
Name: "repo.owner",
Usage: "repository owner",
EnvVar: "DRONE_REPO_OWNER",
},
cli.StringFlag{
Name: "repo.name",
Usage: "repository name",
EnvVar: "DRONE_REPO_NAME",
},
cli.StringFlag{
Name: "commit.sha",
Usage: "git commit sha",
EnvVar: "DRONE_COMMIT_SHA",
},
cli.StringFlag{
Name: "commit.ref",
Value: "refs/heads/master",
Usage: "git commit ref",
EnvVar: "DRONE_COMMIT_REF",
},
cli.StringFlag{
Name: "commit.branch",
Value: "master",
Usage: "git commit branch",
EnvVar: "DRONE_COMMIT_BRANCH",
},
cli.StringFlag{
Name: "commit.author",
Usage: "git author name",
EnvVar: "DRONE_COMMIT_AUTHOR",
},
cli.StringFlag{
Name: "commit.message",
Usage: "commit message",
EnvVar: "DRONE_COMMIT_MESSAGE",
},
cli.StringFlag{
Name: "build.event",
Value: "push",
Usage: "build event",
EnvVar: "DRONE_BUILD_EVENT",
},
cli.IntFlag{
Name: "build.number",
Usage: "build number",
EnvVar: "DRONE_BUILD_NUMBER",
},
cli.StringFlag{
Name: "build.status",
Usage: "build status",
Value: "success",
EnvVar: "DRONE_BUILD_STATUS",
},
cli.StringFlag{
Name: "build.link",
Usage: "build link",
EnvVar: "DRONE_BUILD_LINK",
},
cli.Int64Flag{
Name: "build.started",
Usage: "build started",
EnvVar: "DRONE_BUILD_STARTED",
},
cli.Int64Flag{
Name: "build.created",
Usage: "build created",
EnvVar: "DRONE_BUILD_CREATED",
},
cli.StringFlag{
Name: "build.tag",
Usage: "build tag",
EnvVar: "DRONE_TAG",
},
cli.Int64Flag{
Name: "job.started",
Usage: "job started",
EnvVar: "DRONE_JOB_STARTED",
}, },
} }
flags := [][]cli.Flag{
urfave.BuildFlags(),
urfave.RepoFlags(),
urfave.CommitFlags(),
urfave.StageFlags(),
urfave.StepFlags(),
urfave.SemVerFlags(),
}
for _, flagz := range flags {
app.Flags = append(
app.Flags,
flagz...,
)
}
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
log.Fatal(err) os.Exit(1)
} }
} }
func run(c *cli.Context) error { func run(c *cli.Context) error {
plugin := Plugin{ plugin := Plugin{
Repo: Repo{ Build: urfave.BuildFromContext(c),
Owner: c.String("repo.owner"), Repo: urfave.RepoFromContext(c),
Name: c.String("repo.name"), Commit: urfave.CommitFromContext(c),
}, Stage: urfave.StageFromContext(c),
Build: Build{ Step: urfave.StepFromContext(c),
Tag: c.String("build.tag"), SemVer: urfave.SemVerFromContext(c),
Number: c.Int("build.number"),
Event: c.String("build.event"),
Status: c.String("build.status"),
Commit: c.String("commit.sha"),
Ref: c.String("commit.ref"),
Branch: c.String("commit.branch"),
Author: c.String("commit.author"),
Message: c.String("commit.message"),
Link: c.String("build.link"),
Started: c.Int64("build.started"),
Created: c.Int64("build.created"),
},
Job: Job{
Started: c.Int64("job.started"),
},
Config: Config{ Config: Config{
Method: c.String("method"), Method: c.String(MethodFlag),
Username: c.String("username"), Username: c.String(UsernameFlag),
Password: c.String("password"), Password: c.String(PasswordFlag),
ContentType: c.String("content-type"), ContentType: c.String(ContentTypeFlag),
Template: c.String("template"), Template: c.String(TemplateFlag),
Headers: c.StringSlice("headers"), Headers: c.StringSlice(HeadersFlag),
URLs: c.StringSlice("urls"), URLs: c.StringSlice(URLsFlag),
ValidCodes: c.IntSlice("valid-response-codes"), ValidCodes: c.IntSlice(ValidResponseCodesFlag),
Debug: c.Bool("debug"), Debug: c.Bool(DebugFlag),
SkipVerify: c.Bool("skip-verify"), SkipVerify: c.Bool(SkipVerifyFlag),
}, },
} }
if plugin.Config.Debug {
log.SetLevel(log.DebugLevel)
}
if len(plugin.Config.URLs) == 0 {
log.Fatal("You must provide at least one url")
}
return plugin.Exec() return plugin.Exec()
} }
func init() {
log.SetFormatter(&log.TextFormatter{
DisableColors: true,
DisableTimestamp: true,
})
log.SetOutput(os.Stdout)
log.SetLevel(log.InfoLevel)
}
+89 -107
View File
@@ -8,33 +8,16 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"os"
"strings" "strings"
"github.com/drone-plugins/drone-plugin-lib/pkg/plugin"
"github.com/drone/drone-template-lib/template" "github.com/drone/drone-template-lib/template"
"github.com/jackspirou/syscerts"
log "github.com/sirupsen/logrus"
) )
type ( type (
Repo struct { // Config provides the pugin configuration.
Owner string `json:"owner"`
Name string `json:"name"`
}
Build struct {
Tag string `json:"tag"`
Event string `json:"event"`
Number int `json:"number"`
Commit string `json:"commit"`
Ref string `json:"ref"`
Branch string `json:"branch"`
Author string `json:"author"`
Message string `json:"message"`
Status string `json:"status"`
Link string `json:"link"`
Started int64 `json:"started"`
Created int64 `json:"created"`
}
Config struct { Config struct {
Method string Method string
Username string Username string
@@ -48,76 +31,51 @@ type (
SkipVerify bool SkipVerify bool
} }
Job struct { // Plugin provides all required attributes.
Started int64
}
Plugin struct { Plugin struct {
Repo Repo Build plugin.Build
Build Build Repo plugin.Repo
Commit plugin.Commit
Stage plugin.Stage
Step plugin.Step
SemVer plugin.SemVer
Config Config Config Config
Job Job
} }
) )
// Exec provides the concrete plugin handler.
func (p Plugin) Exec() error { func (p Plugin) Exec() error {
var ( b, err := p.payload()
buf bytes.Buffer
b []byte
)
if len(p.Config.URLs) == 0 { if err != nil {
return fmt.Errorf("You must provide at least one url") return err
} }
if p.Config.Template == "" { for i, raw := range p.Config.URLs {
data := struct { uri, err := url.Parse(raw)
Repo Repo `json:"repo"`
Build Build `json:"build"` if err != nil {
}{p.Repo, p.Build} log.WithFields(log.Fields{
"error": err,
}).Error("Failed to parse hook URL")
if err := json.NewEncoder(&buf).Encode(&data); err != nil {
fmt.Printf("Error: Failed to encode JSON payload. %s\n", err)
return err return err
} }
b = buf.Bytes() req, err := http.NewRequest(p.Config.Method, uri.String(), bytes.NewReader(b))
} else {
txt, err := template.RenderTrim(p.Config.Template, p)
if err != nil { if err != nil {
return err log.WithFields(log.Fields{
} "error": err,
}).Error("Failed to create HTTP request")
text := txt
b = []byte(text)
}
// build and execute a request for each url.
// all auth, headers, method, template (payload),
// and content_type values will be applied to
// every webhook request.
for i, rawurl := range p.Config.URLs {
uri, err := url.Parse(rawurl)
if err != nil {
fmt.Printf("Error: Failed to parse the hook URL. %s\n", err)
os.Exit(1)
}
r := bytes.NewReader(b)
req, err := http.NewRequest(p.Config.Method, uri.String(), r)
if err != nil {
fmt.Printf("Error: Failed to create the HTTP request. %s\n", err)
return err return err
} }
req.Header.Set("Content-Type", p.Config.ContentType) req.Header.Set("Content-Type", p.Config.ContentType)
for _, value := range p.Config.Headers { for _, value := range p.Config.Headers {
header := strings.Split(value, "=") header := strings.SplitN(value, "=", 2)
req.Header.Set(header[0], header[1]) req.Header.Set(header[0], header[1])
} }
@@ -125,22 +83,23 @@ func (p Plugin) Exec() error {
req.SetBasicAuth(p.Config.Username, p.Config.Password) req.SetBasicAuth(p.Config.Username, p.Config.Password)
} }
client := http.DefaultClient client := &http.Client{
Transport: &http.Transport{
if p.Config.SkipVerify { Proxy: http.ProxyFromEnvironment,
client = &http.Client{ TLSClientConfig: &tls.Config{
Transport: &http.Transport{ RootCAs: syscerts.SystemRootsPool(),
TLSClientConfig: &tls.Config{ InsecureSkipVerify: p.Config.SkipVerify,
InsecureSkipVerify: true,
},
}, },
} },
} }
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
fmt.Printf("Error: Failed to execute the HTTP request. %s\n", err) log.WithFields(log.Fields{
"error": err,
}).Error("Failed to execute HTTP request")
return err return err
} }
@@ -150,46 +109,69 @@ func (p Plugin) Exec() error {
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
fmt.Printf("Error: Failed to read the HTTP response body. %s\n", err) log.WithFields(log.Fields{
"error": err,
}).Error("Failed to parse HTTP response")
} }
if p.Config.Debug { output, err := template.RenderTrim(result, webhook{
fmt.Printf( Debug: p.Config.Debug,
debugFormat, Number: i,
i+1, URL: req.URL.String(),
req.URL, Method: req.Method,
req.Method, Header: req.Header,
req.Header, Status: resp.Status,
string(b), Request: string(b),
resp.Status, Response: string(body),
string(body), })
)
} else { if err != nil {
fmt.Printf( log.WithFields(log.Fields{
respFormat, "error": err,
i+1, }).Error("Failed to parse debug template")
req.URL,
resp.Status, return err
string(body),
)
} }
fmt.Println(output)
} }
if len(p.Config.ValidCodes) > 0 && !intInSlice(p.Config.ValidCodes, resp.StatusCode) { if len(p.Config.ValidCodes) > 0 && !intInSlice(p.Config.ValidCodes, resp.StatusCode) {
return fmt.Errorf("Error: Response code %d not found among valid response codes", resp.StatusCode) log.WithFields(log.Fields{
} "code": resp.StatusCode,
}).Error("Valid response code not found")
return fmt.Errorf("valid response code not found")
}
} }
return nil return nil
} }
// Function checks if int is in slice of ints func (p Plugin) payload() ([]byte, error) {
func intInSlice(s []int, e int) bool { if p.Config.Template == "" {
for _, a := range s { res, err := json.Marshal(&p)
if a == e {
return true if err != nil {
log.WithFields(log.Fields{
"error": err,
}).Error("Failed to generate JSON response")
return []byte{}, err
} }
return res, nil
} }
return false
res, err := template.RenderTrim(p.Config.Template, p)
if err != nil {
log.WithFields(log.Fields{
"error": err,
}).Error("Failed to parse response template")
return []byte{}, err
}
return []byte(res), nil
} }
+27
View File
@@ -0,0 +1,27 @@
package main
import (
"net/http"
)
// webhook defines the result payload.
type webhook struct {
Number int
URL string
Method string
Header http.Header
Status string
Request string
Response string
Debug bool
}
// result defines the output template.
const result = `Webhook {{Number}}
URL: {{URL}}{{#if Debug}}
METHOD: {{Method}}
HEADERS: {{Headers}}
REQUEST: {{Request}}{{/if}}
STATUS: {{Status}}
RESPONSE: {{Response}}
`