Skip to content

Commit 30447d3

Browse files
Add github credentials API and cli code
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
1 parent 64e2e13 commit 30447d3

28 files changed

+2364
-175
lines changed

apiserver/controllers/controllers.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,7 @@ func (a *APIController) handleWorkflowJobEvent(ctx context.Context, w http.Respo
102102
handleError(ctx, w, gErrors.NewBadRequestError("invalid post body: %s", err))
103103
return
104104
}
105-
slog.Info("received webhook", "body", string(body))
106-
for k, v := range r.Header {
107-
slog.InfoContext(ctx, "header", "key", k, "value", v)
108-
}
105+
109106
signature := r.Header.Get("X-Hub-Signature-256")
110107
hookType := r.Header.Get("X-Github-Hook-Installation-Target-Type")
111108

apiserver/controllers/credentials.go

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@ package controllers
33
import (
44
"encoding/json"
55
"log/slog"
6+
"math"
67
"net/http"
8+
"strconv"
9+
10+
"github.com/gorilla/mux"
11+
12+
gErrors "github.com/cloudbase/garm-provider-common/errors"
13+
"github.com/cloudbase/garm/params"
714
)
815

916
// swagger:route GET /credentials credentials ListCredentials
17+
// swagger:route GET /github/credentials credentials ListCredentials
1018
//
1119
// List all credentials.
1220
//
@@ -26,3 +34,196 @@ func (a *APIController) ListCredentials(w http.ResponseWriter, r *http.Request)
2634
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
2735
}
2836
}
37+
38+
// swagger:route POST /github/credentials credentials CreateCredentials
39+
//
40+
// Create a GitHub credential.
41+
//
42+
// Parameters:
43+
// + name: Body
44+
// description: Parameters used when creating a GitHub credential.
45+
// type: CreateGithubCredentialsParams
46+
// in: body
47+
// required: true
48+
//
49+
// Responses:
50+
// 200: GithubCredentials
51+
// 400: APIErrorResponse
52+
func (a *APIController) CreateGithubCredential(w http.ResponseWriter, r *http.Request) {
53+
ctx := r.Context()
54+
55+
var params params.CreateGithubCredentialsParams
56+
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
57+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
58+
handleError(ctx, w, gErrors.ErrBadRequest)
59+
return
60+
}
61+
62+
cred, err := a.r.CreateGithubCredentials(ctx, params)
63+
if err != nil {
64+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to create GitHub credential")
65+
handleError(ctx, w, err)
66+
return
67+
}
68+
w.Header().Set("Content-Type", "application/json")
69+
if err := json.NewEncoder(w).Encode(cred); err != nil {
70+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
71+
}
72+
}
73+
74+
// swagger:route GET /github/credentials/{id} credentials GetCredentials
75+
//
76+
// Get a GitHub credential.
77+
//
78+
// Parameters:
79+
// + name: id
80+
// description: ID of the GitHub credential.
81+
// type: integer
82+
// in: path
83+
// required: true
84+
//
85+
// Responses:
86+
// 200: GithubCredentials
87+
// 400: APIErrorResponse
88+
func (a *APIController) GetGithubCredential(w http.ResponseWriter, r *http.Request) {
89+
ctx := r.Context()
90+
vars := mux.Vars(r)
91+
idParam, ok := vars["id"]
92+
if !ok {
93+
slog.ErrorContext(ctx, "missing id in request")
94+
handleError(ctx, w, gErrors.ErrBadRequest)
95+
return
96+
}
97+
98+
id, err := strconv.ParseUint(idParam, 10, 64)
99+
if err != nil {
100+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
101+
handleError(ctx, w, gErrors.ErrBadRequest)
102+
return
103+
}
104+
105+
if id > math.MaxUint {
106+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
107+
handleError(ctx, w, gErrors.ErrBadRequest)
108+
return
109+
}
110+
111+
cred, err := a.r.GetGithubCredentials(ctx, uint(id))
112+
if err != nil {
113+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to get GitHub credential")
114+
handleError(ctx, w, err)
115+
return
116+
}
117+
118+
w.Header().Set("Content-Type", "application/json")
119+
if err := json.NewEncoder(w).Encode(cred); err != nil {
120+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
121+
}
122+
}
123+
124+
// swagger:route DELETE /github/credentials/{id} credentials DeleteCredentials
125+
//
126+
// Delete a GitHub credential.
127+
//
128+
// Parameters:
129+
// + name: id
130+
// description: ID of the GitHub credential.
131+
// type: integer
132+
// in: path
133+
// required: true
134+
//
135+
// Responses:
136+
// default: APIErrorResponse
137+
func (a *APIController) DeleteGithubCredential(w http.ResponseWriter, r *http.Request) {
138+
ctx := r.Context()
139+
vars := mux.Vars(r)
140+
idParam, ok := vars["id"]
141+
if !ok {
142+
slog.ErrorContext(ctx, "missing id in request")
143+
handleError(ctx, w, gErrors.ErrBadRequest)
144+
return
145+
}
146+
147+
id, err := strconv.ParseUint(idParam, 10, 64)
148+
if err != nil {
149+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
150+
handleError(ctx, w, gErrors.ErrBadRequest)
151+
return
152+
}
153+
154+
if id > math.MaxUint {
155+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
156+
handleError(ctx, w, gErrors.ErrBadRequest)
157+
return
158+
}
159+
160+
if err := a.r.DeleteGithubCredentials(ctx, uint(id)); err != nil {
161+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to delete GitHub credential")
162+
handleError(ctx, w, err)
163+
return
164+
}
165+
166+
w.WriteHeader(http.StatusNoContent)
167+
}
168+
169+
// swagger:route PUT /github/credentials/{id} credentials UpdateCredentials
170+
//
171+
// Update a GitHub credential.
172+
//
173+
// Parameters:
174+
// + name: id
175+
// description: ID of the GitHub credential.
176+
// type: integer
177+
// in: path
178+
// required: true
179+
// + name: Body
180+
// description: Parameters used when updating a GitHub credential.
181+
// type: UpdateGithubCredentialsParams
182+
// in: body
183+
// required: true
184+
//
185+
// Responses:
186+
// 200: GithubCredentials
187+
// 400: APIErrorResponse
188+
func (a *APIController) UpdateGithubCredential(w http.ResponseWriter, r *http.Request) {
189+
ctx := r.Context()
190+
vars := mux.Vars(r)
191+
idParam, ok := vars["id"]
192+
if !ok {
193+
slog.ErrorContext(ctx, "missing id in request")
194+
handleError(ctx, w, gErrors.ErrBadRequest)
195+
return
196+
}
197+
198+
id, err := strconv.ParseUint(idParam, 10, 64)
199+
if err != nil {
200+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
201+
handleError(ctx, w, gErrors.ErrBadRequest)
202+
return
203+
}
204+
205+
if id > math.MaxUint {
206+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
207+
handleError(ctx, w, gErrors.ErrBadRequest)
208+
return
209+
}
210+
211+
var params params.UpdateGithubCredentialsParams
212+
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
213+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
214+
handleError(ctx, w, gErrors.ErrBadRequest)
215+
return
216+
}
217+
218+
cred, err := a.r.UpdateGithubCredentials(ctx, uint(id), params)
219+
if err != nil {
220+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to update GitHub credential")
221+
handleError(ctx, w, err)
222+
return
223+
}
224+
225+
w.Header().Set("Content-Type", "application/json")
226+
if err := json.NewEncoder(w).Encode(cred); err != nil {
227+
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
228+
}
229+
}

apiserver/routers/routers.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,6 @@ func NewAPIRouter(han *controllers.APIController, authMiddleware, initMiddleware
339339
apiRouter.Handle("/enterprises/", http.HandlerFunc(han.CreateEnterpriseHandler)).Methods("POST", "OPTIONS")
340340
apiRouter.Handle("/enterprises", http.HandlerFunc(han.CreateEnterpriseHandler)).Methods("POST", "OPTIONS")
341341

342-
// Credentials
343-
apiRouter.Handle("/credentials/", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
344-
apiRouter.Handle("/credentials", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
345-
346342
// Providers
347343
apiRouter.Handle("/providers/", http.HandlerFunc(han.ListProviders)).Methods("GET", "OPTIONS")
348344
apiRouter.Handle("/providers", http.HandlerFunc(han.ListProviders)).Methods("GET", "OPTIONS")
@@ -370,6 +366,28 @@ func NewAPIRouter(han *controllers.APIController, authMiddleware, initMiddleware
370366
apiRouter.Handle("/github/endpoints/{name}/", http.HandlerFunc(han.UpdateGithubEndpoint)).Methods("PUT", "OPTIONS")
371367
apiRouter.Handle("/github/endpoints/{name}", http.HandlerFunc(han.UpdateGithubEndpoint)).Methods("PUT", "OPTIONS")
372368

369+
////////////////////////
370+
// Github credentials //
371+
////////////////////////
372+
// Legacy credentials path
373+
apiRouter.Handle("/credentials/", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
374+
apiRouter.Handle("/credentials", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
375+
// List Github Credentials
376+
apiRouter.Handle("/github/credentials/", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
377+
apiRouter.Handle("/github/credentials", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
378+
// Create Github Credentials
379+
apiRouter.Handle("/github/credentials/", http.HandlerFunc(han.CreateGithubCredential)).Methods("POST", "OPTIONS")
380+
apiRouter.Handle("/github/credentials", http.HandlerFunc(han.CreateGithubCredential)).Methods("POST", "OPTIONS")
381+
// Get Github Credential
382+
apiRouter.Handle("/github/credentials/{id}/", http.HandlerFunc(han.GetGithubCredential)).Methods("GET", "OPTIONS")
383+
apiRouter.Handle("/github/credentials/{id}", http.HandlerFunc(han.GetGithubCredential)).Methods("GET", "OPTIONS")
384+
// Delete Github Credential
385+
apiRouter.Handle("/github/credentials/{id}/", http.HandlerFunc(han.DeleteGithubCredential)).Methods("DELETE", "OPTIONS")
386+
apiRouter.Handle("/github/credentials/{id}", http.HandlerFunc(han.DeleteGithubCredential)).Methods("DELETE", "OPTIONS")
387+
// Update Github Credential
388+
apiRouter.Handle("/github/credentials/{id}/", http.HandlerFunc(han.UpdateGithubCredential)).Methods("PUT", "OPTIONS")
389+
apiRouter.Handle("/github/credentials/{id}", http.HandlerFunc(han.UpdateGithubCredential)).Methods("PUT", "OPTIONS")
390+
373391
// Websocket log writer
374392
apiRouter.Handle("/{ws:ws\\/?}", http.HandlerFunc(han.WSHandler)).Methods("GET")
375393

apiserver/swagger-models.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,18 @@ definitions:
263263
type: CreateGithubEndpointParams
264264
import:
265265
package: github.com/cloudbase/garm/params
266-
alias: garm_params
266+
alias: garm_params
267+
CreateGithubCredentialsParams:
268+
type: object
269+
x-go-type:
270+
type: CreateGithubCredentialsParams
271+
import:
272+
package: github.com/cloudbase/garm/params
273+
alias: garm_params
274+
UpdateGithubCredentialsParams:
275+
type: object
276+
x-go-type:
277+
type: UpdateGithubCredentialsParams
278+
import:
279+
package: github.com/cloudbase/garm/params
280+
alias: garm_params

0 commit comments

Comments
 (0)