Skip to content

Commit f02fb45

Browse files
committed
option to return ErrSkip and ErrBlock from validator
1 parent 195394d commit f02fb45

File tree

7 files changed

+149
-1
lines changed

7 files changed

+149
-1
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module github.com/drone/drone-go
22

3+
go 1.14
4+
35
require (
46
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e
57
github.com/google/go-cmp v0.2.0

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e h1:rl2Aq4ZODqTDkeSqQBy+fzpZPamacO1Srp8zq7jf2Sc=
2+
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY=
3+
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
4+
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=

plugin/validator/client.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package validator
1717
import (
1818
"context"
1919

20+
"github.com/drone/drone-go/drone"
2021
"github.com/drone/drone-go/plugin/internal/client"
2122
)
2223

@@ -34,5 +35,14 @@ type pluginClient struct {
3435
}
3536

3637
func (c *pluginClient) Validate(ctx context.Context, in *Request) error {
37-
return c.client.Do(in, nil)
38+
err := c.client.Do(in, nil)
39+
if xerr, ok := err.(*drone.Error); ok {
40+
if xerr.Code == 498 {
41+
return ErrSkip
42+
}
43+
if xerr.Code == 499 {
44+
return ErrBlock
45+
}
46+
}
47+
return err
3848
}

plugin/validator/client_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2018 Drone.IO Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package validator
16+
17+
// import (
18+
// "bytes"
19+
// "context"
20+
// "io/ioutil"
21+
// "net/http"
22+
// "testing"
23+
// )
24+
25+
// var noContext = context.Background()
26+
27+
// func TestErrSkip(t *testing.T) {
28+
// client := http.Client{}
29+
// client.Transport = roundTripFunc(func(r *http.Request) (*http.Response, error) {
30+
// buf := bytes.NewBuffer(nil)
31+
// buf.WriteString("skip")
32+
// return &http.Response{
33+
// Body: ioutil.NopCloser(buf),
34+
// StatusCode: 498,
35+
// }, nil
36+
// })
37+
38+
// plugin := Client("http://localhost", "top-secret", false)
39+
// plugin.(*pluginClient).client.Client = &client
40+
41+
// err := plugin.Validate(noContext, &Request{})
42+
// if err != ErrSkip {
43+
// t.Errorf("Expect skip error, got %v", err)
44+
// }
45+
// }
46+
47+
// type roundTripFunc func(r *http.Request) (*http.Response, error)
48+
49+
// func (s roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) {
50+
// return s(r)
51+
// }

plugin/validator/handler.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ func (p *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
9090
return
9191
}
9292

93+
if err == ErrSkip {
94+
w.WriteHeader(498)
95+
return
96+
}
97+
98+
if err == ErrBlock {
99+
w.WriteHeader(499)
100+
return
101+
}
102+
93103
// The error should be converted to a drone.Error so that
94104
// it can be marshaled to JSON.
95105
if _, ok := err.(*drone.Error); !ok {

plugin/validator/handler_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,68 @@ func TestHandler_Error(t *testing.T) {
9898
}
9999
}
100100

101+
func TestHandler_ErrorSkip(t *testing.T) {
102+
key := "xVKAGlWQiY3sOp8JVc0nbuNId3PNCgWh"
103+
104+
buf := new(bytes.Buffer)
105+
json.NewEncoder(buf).Encode(&Request{
106+
Config: drone.Config{
107+
Data: "{kind: pipeline, type: docker}",
108+
},
109+
})
110+
111+
res := httptest.NewRecorder()
112+
req := httptest.NewRequest("GET", "/", buf)
113+
req.Header.Add("Date", time.Now().UTC().Format(http.TimeFormat))
114+
115+
err := httpsignatures.DefaultSha256Signer.AuthRequest("hmac-key", key, req)
116+
if err != nil {
117+
t.Error(err)
118+
return
119+
}
120+
121+
err = ErrSkip
122+
plugin := &mockPlugin{err: err}
123+
124+
handler := Handler(key, plugin, nil)
125+
handler.ServeHTTP(res, req)
126+
127+
if got, want := res.Code, 498; got != want {
128+
t.Errorf("Want status code %d, got %d", want, got)
129+
}
130+
}
131+
132+
func TestHandler_ErrorBlock(t *testing.T) {
133+
key := "xVKAGlWQiY3sOp8JVc0nbuNId3PNCgWh"
134+
135+
buf := new(bytes.Buffer)
136+
json.NewEncoder(buf).Encode(&Request{
137+
Config: drone.Config{
138+
Data: "{kind: pipeline, type: docker}",
139+
},
140+
})
141+
142+
res := httptest.NewRecorder()
143+
req := httptest.NewRequest("GET", "/", buf)
144+
req.Header.Add("Date", time.Now().UTC().Format(http.TimeFormat))
145+
146+
err := httpsignatures.DefaultSha256Signer.AuthRequest("hmac-key", key, req)
147+
if err != nil {
148+
t.Error(err)
149+
return
150+
}
151+
152+
err = ErrBlock
153+
plugin := &mockPlugin{err: err}
154+
155+
handler := Handler(key, plugin, nil)
156+
handler.ServeHTTP(res, req)
157+
158+
if got, want := res.Code, 499; got != want {
159+
t.Errorf("Want status code %d, got %d", want, got)
160+
}
161+
}
162+
101163
func TestHandler_MissingSignature(t *testing.T) {
102164
res := httptest.NewRecorder()
103165
req := httptest.NewRequest("GET", "/", nil)

plugin/validator/validater.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,22 @@ package validator
1616

1717
import (
1818
"context"
19+
"errors"
1920

2021
"github.com/drone/drone-go/drone"
2122
)
2223

2324
// V1 is version 1 of the validator API
2425
const V1 = "application/vnd.drone.validate.v1+json"
2526

27+
// ErrSkip is returned when the build should be skipped
28+
// instead of throwing an error.
29+
var ErrSkip = errors.New("skip")
30+
31+
// ErrBlock is returned when the build should be blocked
32+
// instead of throwing an error.
33+
var ErrBlock = errors.New("block")
34+
2635
type (
2736
// Request defines a validator request.
2837
Request struct {

0 commit comments

Comments
 (0)