Browse code

UPSTREAM: implement a generic webhook storage

Clayton Coleman authored on 2015/05/06 13:16:02
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,110 @@
0
+/*
1
+Copyright 2015 The Kubernetes Authors All rights reserved.
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
+
16
+package rest
17
+
18
+import (
19
+	"net/http"
20
+
21
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
22
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
23
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
24
+)
25
+
26
+// HookHandler is a Kubernetes API compatible webhook that is able to get access to the raw request
27
+// and response. Used when adapting existing webhook code to the Kubernetes patterns.
28
+type HookHandler interface {
29
+	ServeHTTP(w http.ResponseWriter, r *http.Request, ctx api.Context, name, subpath string) error
30
+}
31
+
32
+type httpHookHandler struct {
33
+	http.Handler
34
+}
35
+
36
+func (h httpHookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request, ctx api.Context, name, subpath string) error {
37
+	h.Handler.ServeHTTP(w, r)
38
+	return nil
39
+}
40
+
41
+// WebHook provides a reusable rest.Storage implementation for linking a generic WebHook handler
42
+// into the Kube API pattern. It is intended to be used with GET or POST against a resource's
43
+// named path, possibly as a subresource. The handler has access to the extracted information
44
+// from the Kube apiserver including the context, the name, and the subpath.
45
+type WebHook struct {
46
+	h        HookHandler
47
+	allowGet bool
48
+}
49
+
50
+var _ rest.Connecter = &WebHook{}
51
+
52
+func NewWebHook(handler HookHandler, allowGet bool) *WebHook {
53
+	return &WebHook{
54
+		h:        handler,
55
+		allowGet: allowGet,
56
+	}
57
+}
58
+
59
+func NewHTTPWebHook(handler http.Handler, allowGet bool) *WebHook {
60
+	return &WebHook{
61
+		h:        httpHookHandler{handler},
62
+		allowGet: allowGet,
63
+	}
64
+}
65
+
66
+func (h *WebHook) New() runtime.Object {
67
+	return &api.Status{}
68
+}
69
+
70
+func (h *WebHook) Connect(ctx api.Context, name string, options runtime.Object) (rest.ConnectHandler, error) {
71
+	return &WebHookHandler{
72
+		handler: h.h,
73
+		ctx:     ctx,
74
+		name:    name,
75
+		options: options.(*api.PodProxyOptions),
76
+	}, nil
77
+}
78
+
79
+func (h *WebHook) NewConnectOptions() (runtime.Object, bool, string) {
80
+	return &api.PodProxyOptions{}, true, "path"
81
+}
82
+
83
+func (h *WebHook) ConnectMethods() []string {
84
+	if h.allowGet {
85
+		return []string{"GET", "POST"}
86
+	}
87
+	return []string{"POST"}
88
+}
89
+
90
+type WebHookHandler struct {
91
+	handler HookHandler
92
+	ctx     api.Context
93
+	name    string
94
+	options *api.PodProxyOptions
95
+	err     error
96
+}
97
+
98
+var _ rest.ConnectHandler = &WebHookHandler{}
99
+
100
+func (h *WebHookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
101
+	h.err = h.handler.ServeHTTP(w, r, h.ctx, h.name, h.options.Path)
102
+	if h.err == nil {
103
+		w.WriteHeader(http.StatusOK)
104
+	}
105
+}
106
+
107
+func (h *WebHookHandler) RequestError() error {
108
+	return h.err
109
+}