forked from tektoncd/triggers
/
interceptors.go
88 lines (74 loc) · 2.58 KB
/
interceptors.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
/*
Copyright 2019 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sink
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"golang.org/x/xerrors"
corev1 "k8s.io/api/core/v1"
)
// GetURI retrieves the ObjectReference to URI.
func GetURI(objRef *corev1.ObjectReference, ns string) (*url.URL, error) {
// TODO: This should work for any Adressable.
// Use something like https://github.com/knative/eventing-contrib/blob/7c0fc5cfa8bd44da0767d9e7b250264ea6eb7d8d/pkg/controller/sinks/sinks.go#L32
if objRef.Kind == "Service" && objRef.APIVersion == "v1" {
// TODO: Also assuming port 80 and http here. Use DNS/or the env vars?
if objRef.Namespace != "" {
ns = objRef.Namespace
}
return url.Parse(fmt.Sprintf("http://%s.%s.svc/", objRef.Name, ns))
}
return nil, xerrors.New("Invalid objRef")
}
// TODO: Use request.Clone once we move to go 1.13
func createOutgoingRequest(ctx context.Context, original *http.Request, url *url.URL, payload []byte) *http.Request {
r := original.WithContext(ctx)
// RequestURI cannot be set in outgoing requests
r.RequestURI = ""
r.URL = url
headers := make(map[string][]string, len(original.Header))
for k, v := range original.Header {
v2 := make([]string, len(v))
copy(v2, v)
headers[k] = v2
}
r.Header = headers
if s := original.TransferEncoding; s != nil {
s2 := make([]string, len(s))
copy(s2, s)
r.TransferEncoding = s
}
r.Body = ioutil.NopCloser(bytes.NewBuffer(payload))
return r
}
func makeRequest(client *http.Client, request *http.Request) ([]byte, error) {
resp, err := client.Do(request)
if err != nil {
// TODO: Add Error types - ValidationError and other General ProcessingErrors
return nil, xerrors.Errorf("Failed to proxy request to interceptor: %w", err.Error())
}
defer resp.Body.Close()
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, xerrors.Errorf("Failed to parse response body")
}
// Wrap error and return
if resp.StatusCode != http.StatusOK {
return nil, xerrors.Errorf("Request rejected; status: %s; message: %s", resp.Status, respBody)
}
return respBody, nil
}