-
Notifications
You must be signed in to change notification settings - Fork 2
/
api.go
135 lines (113 loc) · 3.17 KB
/
api.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package kubeci
import (
"context"
"fmt"
"net/http"
"strings"
"encoding/json"
workflow "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
)
type APIHandler struct {
Storage pvcManager
Clients githubClientSource
Runner workflowRunner
Slash slashRunner
UIBase string
GitHubSecret []byte
AppID int64
InstallID int
}
type RunResp struct {
Workflow *workflow.Workflow `json:"workflow,omitempty"`
Debug string `json:"debug,omitempty"`
}
type RunRequest struct {
Org string `json:"org"`
Repo string `json:"repo"`
Ref string `json:"ref"`
RefType string `json:"ref_type,omitempty"`
Hash string `json:"hash"`
CIContext map[string]string `json:"ci_context"`
Entrypoint string `json:"entrypoint"`
Run bool `json:"run"`
}
func (h *APIHandler) handleRun(ctx context.Context, w http.ResponseWriter, r *RunRequest) (RunResp, error) {
ghClient, err := h.Clients.getClient(r.Org, h.InstallID, r.Repo)
if err != nil {
return RunResp{}, fmt.Errorf("could not get github client, %w", err)
}
repo, err := ghClient.GetRepo(ctx)
if err != nil {
return RunResp{}, fmt.Errorf("could not get github repo, %w", err)
}
refType := "branch"
if r.RefType != "" {
refType = r.RefType
}
// We'll tidy up the filenames
var ciContext map[string]string
if r.CIContext != nil {
ciContext = make(map[string]string, len(r.CIContext))
for k, v := range r.CIContext {
ciContext[strings.TrimPrefix(k, "/")] = v
}
}
wctx := WorkflowContext{
Repo: repo,
Ref: r.Ref,
RefType: refType,
SHA: r.Hash,
Entrypoint: r.Entrypoint,
ContextData: ciContext,
Event: nil,
PRs: nil,
}
wf, debug, err := h.Runner.getWorkflow(ctx, ghClient, &wctx)
if err != nil {
return RunResp{Debug: debug}, fmt.Errorf("could not get workflow, %w", err)
}
if !r.Run {
return RunResp{
Workflow: wf,
Debug: debug,
}, nil
}
return RunResp{}, fmt.Errorf("only dry run is supported at present")
}
func (h *APIHandler) HandleRun(w http.ResponseWriter, r *http.Request) {
req := RunRequest{}
dec := json.NewDecoder(r.Body)
dec.DisallowUnknownFields()
err := dec.Decode(&req)
if err != nil {
http.Error(w, fmt.Sprintf("cannot decode input, %v", err), http.StatusBadRequest)
return
}
switch {
case req.Org == "":
err = fmt.Errorf("org must be specified")
case req.Repo == "":
err = fmt.Errorf("repo must be specified")
case req.Ref == "":
err = fmt.Errorf("ref must be specified")
case req.Hash == "":
err = fmt.Errorf("hash must be specified")
}
if err != nil {
http.Error(w, fmt.Sprintf("cannot decode input, %v", err), http.StatusBadRequest)
return
}
resp, err := h.handleRun(r.Context(), w, &req)
if err != nil {
http.Error(w, fmt.Sprintf("cannot decode input, %v", err), http.StatusBadRequest)
}
err = json.NewEncoder(w).Encode(resp)
if err != nil {
http.Error(w, fmt.Sprintf("cannot encode response, %v", err), http.StatusInternalServerError)
}
}
func NewAPIHandler(h APIHandler) http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/run", h.HandleRun)
return mux
}