forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
webhook.go
99 lines (86 loc) · 3.24 KB
/
webhook.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package webhook
import (
"crypto/hmac"
"errors"
"net/http"
"strings"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kapi "k8s.io/kubernetes/pkg/api"
buildapi "github.com/openshift/origin/pkg/build/apis/build"
)
const (
refPrefix = "refs/heads/"
DefaultConfigRef = "master"
)
var (
ErrSecretMismatch = errors.New("the provided secret does not match")
ErrHookNotEnabled = errors.New("the specified hook is not enabled")
MethodNotSupported = errors.New("unsupported HTTP method")
)
// Plugin for Webhook verification is dependent on the sending side, it can be
// eg. github, bitbucket or else, so there must be a separate Plugin
// instance for each webhook provider.
type Plugin interface {
// Method extracts build information and returns:
// - newly created build object or nil if default is to be created
// - information whether to trigger the build itself
// - eventual error.
Extract(buildCfg *buildapi.BuildConfig, secret, path string, req *http.Request) (*buildapi.SourceRevision, []kapi.EnvVar, *buildapi.DockerStrategyOptions, bool, error)
}
// GitRefMatches determines if the ref from a webhook event matches a build
// configuration
func GitRefMatches(eventRef, configRef string, buildSource *buildapi.BuildSource) bool {
if buildSource.Git != nil && len(buildSource.Git.Ref) != 0 {
configRef = buildSource.Git.Ref
}
eventRef = strings.TrimPrefix(eventRef, refPrefix)
configRef = strings.TrimPrefix(configRef, refPrefix)
return configRef == eventRef
}
// FindTriggerPolicy retrieves the BuildTrigger of a given type from a build
// configuration
func FindTriggerPolicy(triggerType buildapi.BuildTriggerType, config *buildapi.BuildConfig) (buildTriggers []buildapi.BuildTriggerPolicy, err error) {
buildTriggers = buildapi.FindTriggerPolicy(triggerType, config)
if len(buildTriggers) == 0 {
err = ErrHookNotEnabled
}
return buildTriggers, err
}
// ValidateWebHookSecret validates the provided secret against all currently
// defined webhook secrets and if it is valid, returns its information.
func ValidateWebHookSecret(webHookTriggers []buildapi.BuildTriggerPolicy, secret string) (*buildapi.WebHookTrigger, error) {
for _, trigger := range webHookTriggers {
switch trigger.Type {
case buildapi.GenericWebHookBuildTriggerType:
if !hmac.Equal([]byte(trigger.GenericWebHook.Secret), []byte(secret)) {
continue
}
return trigger.GenericWebHook, nil
case buildapi.GitHubWebHookBuildTriggerType:
if !hmac.Equal([]byte(trigger.GitHubWebHook.Secret), []byte(secret)) {
continue
}
return trigger.GitHubWebHook, nil
case buildapi.GitLabWebHookBuildTriggerType:
if !hmac.Equal([]byte(trigger.GitLabWebHook.Secret), []byte(secret)) {
continue
}
return trigger.GitLabWebHook, nil
case buildapi.BitbucketWebHookBuildTriggerType:
if !hmac.Equal([]byte(trigger.BitbucketWebHook.Secret), []byte(secret)) {
continue
}
return trigger.BitbucketWebHook, nil
}
}
return nil, ErrSecretMismatch
}
// NewWarning returns an StatusError object with a http.StatusOK (200) code.
func NewWarning(message string) *kerrors.StatusError {
return &kerrors.StatusError{ErrStatus: metav1.Status{
Status: metav1.StatusSuccess,
Code: http.StatusOK,
Message: message,
}}
}