Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: go/src/infra/appengine/sheriff-o-matic/main.go

Issue 2080243005: appengine, crimson: Use updated router API (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « DEPS ('k') | go/src/infra/appengine/sheriff-o-matic/main_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Package som implements HTTP server that handles requests to default module. 5 // Package som implements HTTP server that handles requests to default module.
6 package som 6 package som
7 7
8 import ( 8 import (
9 "crypto/sha1" 9 "crypto/sha1"
10 "encoding/json" 10 "encoding/json"
11 "fmt" 11 "fmt"
12 "html/template" 12 "html/template"
13 "infra/monorail" 13 "infra/monorail"
14 "io/ioutil" 14 "io/ioutil"
15 "net/http" 15 "net/http"
16 "strings" 16 "strings"
17 17
18 "github.com/julienschmidt/httprouter"
19 "golang.org/x/net/context" 18 "golang.org/x/net/context"
20 "google.golang.org/appengine" 19 "google.golang.org/appengine"
21 20
22 "github.com/luci/gae/service/datastore" 21 "github.com/luci/gae/service/datastore"
23 "github.com/luci/gae/service/urlfetch" 22 "github.com/luci/gae/service/urlfetch"
24 "github.com/luci/luci-go/appengine/gaeauth/client" 23 "github.com/luci/luci-go/appengine/gaeauth/client"
25 "github.com/luci/luci-go/appengine/gaeauth/server" 24 "github.com/luci/luci-go/appengine/gaeauth/server"
26 "github.com/luci/luci-go/appengine/gaemiddleware" 25 "github.com/luci/luci-go/appengine/gaemiddleware"
27 "github.com/luci/luci-go/common/clock" 26 "github.com/luci/luci-go/common/clock"
28 "github.com/luci/luci-go/common/logging" 27 "github.com/luci/luci-go/common/logging"
29 "github.com/luci/luci-go/server/auth" 28 "github.com/luci/luci-go/server/auth"
30 "github.com/luci/luci-go/server/auth/identity" 29 "github.com/luci/luci-go/server/auth/identity"
31 » "github.com/luci/luci-go/server/middleware" 30 » "github.com/luci/luci-go/server/router"
32 "github.com/luci/luci-go/server/settings" 31 "github.com/luci/luci-go/server/settings"
33 ) 32 )
34 33
35 const authGroup = "sheriff-o-matic-access" 34 const authGroup = "sheriff-o-matic-access"
36 35
37 var ( 36 var (
38 mainPage = template.Must(template.ParseFiles("./index.html")) 37 mainPage = template.Must(template.ParseFiles("./index.html"))
39 accessDeniedPage = template.Must(template.ParseFiles("./access-denied.ht ml")) 38 accessDeniedPage = template.Must(template.ParseFiles("./access-denied.ht ml"))
40 monorailEndpoint = "https://monorail-prod.appspot.com/_ah/api/monorail/v 1/" 39 monorailEndpoint = "https://monorail-prod.appspot.com/_ah/api/monorail/v 1/"
41 ) 40 )
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 if alertStreams, ok := values["AlertStreams"]; ok && alertStreams != "" { 168 if alertStreams, ok := values["AlertStreams"]; ok && alertStreams != "" {
170 if err := writeAlertStreams(c, alertStreams); err != nil { 169 if err := writeAlertStreams(c, alertStreams); err != nil {
171 return err 170 return err
172 } 171 }
173 } 172 }
174 173
175 return nil 174 return nil
176 } 175 }
177 176
178 //// Handlers. 177 //// Handlers.
179 func indexPage(c context.Context, w http.ResponseWriter, r *http.Request, p http router.Params) { 178 func indexPage(ctx *router.Context) {
179 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
180 if p.ByName("path") == "" { 180 if p.ByName("path") == "" {
181 http.Redirect(w, r, "/chromium", http.StatusFound) 181 http.Redirect(w, r, "/chromium", http.StatusFound)
182 return 182 return
183 } 183 }
184 184
185 user := auth.CurrentIdentity(c) 185 user := auth.CurrentIdentity(c)
186 186
187 if user.Kind() == identity.Anonymous { 187 if user.Kind() == identity.Anonymous {
188 url, err := auth.LoginURL(c, "/") 188 url, err := auth.LoginURL(c, "/")
189 if err != nil { 189 if err != nil {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 "User": user.Email(), 225 "User": user.Email(),
226 "LogoutUrl": logoutURL, 226 "LogoutUrl": logoutURL,
227 } 227 }
228 228
229 err = mainPage.Execute(w, data) 229 err = mainPage.Execute(w, data)
230 if err != nil { 230 if err != nil {
231 logging.Errorf(c, "while rendering index: %s", err) 231 logging.Errorf(c, "while rendering index: %s", err)
232 } 232 }
233 } 233 }
234 234
235 func getTreesHandler(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) { 235 func getTreesHandler(ctx *router.Context) {
236 » c, w := ctx.Context, ctx.Writer
237
236 if !requireGoogler(w, c) { 238 if !requireGoogler(w, c) {
237 return 239 return
238 } 240 }
239 241
240 q := datastore.NewQuery("Tree") 242 q := datastore.NewQuery("Tree")
241 results := []*Tree{} 243 results := []*Tree{}
242 err := datastore.Get(c).GetAll(q, &results) 244 err := datastore.Get(c).GetAll(q, &results)
243 if err != nil { 245 if err != nil {
244 errStatus(w, http.StatusInternalServerError, err.Error()) 246 errStatus(w, http.StatusInternalServerError, err.Error())
245 return 247 return
246 } 248 }
247 249
248 txt, err := json.Marshal(results) 250 txt, err := json.Marshal(results)
249 if err != nil { 251 if err != nil {
250 errStatus(w, http.StatusInternalServerError, err.Error()) 252 errStatus(w, http.StatusInternalServerError, err.Error())
251 return 253 return
252 } 254 }
253 255
254 w.Header().Set("Content-Type", "application/json") 256 w.Header().Set("Content-Type", "application/json")
255 w.Write(txt) 257 w.Write(txt)
256 } 258 }
257 259
258 func getAlertsHandler(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) { 260 func getAlertsHandler(ctx *router.Context) {
261 » c, w, p := ctx.Context, ctx.Writer, ctx.Params
262
259 if !requireGoogler(w, c) { 263 if !requireGoogler(w, c) {
260 return 264 return
261 } 265 }
262 266
263 ds := datastore.Get(c) 267 ds := datastore.Get(c)
264 268
265 tree := p.ByName("tree") 269 tree := p.ByName("tree")
266 q := datastore.NewQuery("AlertsJSON") 270 q := datastore.NewQuery("AlertsJSON")
267 q = q.Ancestor(ds.MakeKey("Tree", tree)) 271 q = q.Ancestor(ds.MakeKey("Tree", tree))
268 q = q.Order("-Date") 272 q = q.Order("-Date")
(...skipping 10 matching lines...) Expand all
279 logging.Warningf(c, "No alerts found for tree %s", tree) 283 logging.Warningf(c, "No alerts found for tree %s", tree)
280 errStatus(w, http.StatusNotFound, fmt.Sprintf("Tree \"%s\" not f ound", tree)) 284 errStatus(w, http.StatusNotFound, fmt.Sprintf("Tree \"%s\" not f ound", tree))
281 return 285 return
282 } 286 }
283 287
284 alertsJSON := results[0] 288 alertsJSON := results[0]
285 w.Header().Set("Content-Type", "application/json") 289 w.Header().Set("Content-Type", "application/json")
286 w.Write(alertsJSON.Contents) 290 w.Write(alertsJSON.Contents)
287 } 291 }
288 292
289 func postAlertsHandler(c context.Context, w http.ResponseWriter, r *http.Request , p httprouter.Params) { 293 func postAlertsHandler(ctx *router.Context) {
294 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
295
290 if !requireGoogler(w, c) { 296 if !requireGoogler(w, c) {
291 return 297 return
292 } 298 }
293 299
294 tree := p.ByName("tree") 300 tree := p.ByName("tree")
295 ds := datastore.Get(c) 301 ds := datastore.Get(c)
296 302
297 alerts := AlertsJSON{ 303 alerts := AlertsJSON{
298 Tree: ds.MakeKey("Tree", tree), 304 Tree: ds.MakeKey("Tree", tree),
299 Date: clock.Now(c), 305 Date: clock.Now(c),
(...skipping 26 matching lines...) Expand all
326 } 332 }
327 333
328 alerts.Contents = data 334 alerts.Contents = data
329 err = datastore.Get(c).Put(&alerts) 335 err = datastore.Get(c).Put(&alerts)
330 if err != nil { 336 if err != nil {
331 errStatus(w, http.StatusInternalServerError, err.Error()) 337 errStatus(w, http.StatusInternalServerError, err.Error())
332 return 338 return
333 } 339 }
334 } 340 }
335 341
336 func getAnnotationsHandler(c context.Context, w http.ResponseWriter, r *http.Req uest, p httprouter.Params) { 342 func getAnnotationsHandler(ctx *router.Context) {
343 » c, w := ctx.Context, ctx.Writer
344
337 if !requireGoogler(w, c) { 345 if !requireGoogler(w, c) {
338 return 346 return
339 } 347 }
340 348
341 q := datastore.NewQuery("Annotation") 349 q := datastore.NewQuery("Annotation")
342 results := []*Annotation{} 350 results := []*Annotation{}
343 datastore.Get(c).GetAll(q, &results) 351 datastore.Get(c).GetAll(q, &results)
344 352
345 data, err := json.Marshal(results) 353 data, err := json.Marshal(results)
346 if err != nil { 354 if err != nil {
347 errStatus(w, http.StatusInternalServerError, err.Error()) 355 errStatus(w, http.StatusInternalServerError, err.Error())
348 return 356 return
349 } 357 }
350 358
351 w.Header().Set("Content-Type", "application/json") 359 w.Header().Set("Content-Type", "application/json")
352 w.Write(data) 360 w.Write(data)
353 } 361 }
354 362
355 func postAnnotationsHandler(c context.Context, w http.ResponseWriter, r *http.Re quest, p httprouter.Params) { 363 func postAnnotationsHandler(ctx *router.Context) {
364 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
365
356 if !requireGoogler(w, c) { 366 if !requireGoogler(w, c) {
357 return 367 return
358 } 368 }
359 369
360 annKey := p.ByName("annKey") 370 annKey := p.ByName("annKey")
361 action := p.ByName("action") 371 action := p.ByName("action")
362 ds := datastore.Get(c) 372 ds := datastore.Get(c)
363 373
364 if !(action == "add" || action == "remove") { 374 if !(action == "add" || action == "remove") {
365 errStatus(w, http.StatusNotFound, "Invalid action") 375 errStatus(w, http.StatusNotFound, "Invalid action")
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 data, err := json.Marshal(annotation) 414 data, err := json.Marshal(annotation)
405 if err != nil { 415 if err != nil {
406 errStatus(w, http.StatusInternalServerError, err.Error()) 416 errStatus(w, http.StatusInternalServerError, err.Error())
407 return 417 return
408 } 418 }
409 419
410 w.Header().Set("Content-Type", "application/json") 420 w.Header().Set("Content-Type", "application/json")
411 w.Write(data) 421 w.Write(data)
412 } 422 }
413 423
414 func getBugQueueHandler(c context.Context, w http.ResponseWriter, r *http.Reques t, p httprouter.Params) { 424 func getBugQueueHandler(ctx *router.Context) {
425 » c, w, p := ctx.Context, ctx.Writer, ctx.Params
426
415 c = client.UseServiceAccountTransport(c, nil, nil) 427 c = client.UseServiceAccountTransport(c, nil, nil)
416 mr := monorail.NewEndpointsClient(&http.Client{Transport: urlfetch.Get(c )}, monorailEndpoint) 428 mr := monorail.NewEndpointsClient(&http.Client{Transport: urlfetch.Get(c )}, monorailEndpoint)
417 tree := p.ByName("tree") 429 tree := p.ByName("tree")
418 430
419 // TODO(martiniss): make this look up request info based on Tree datasto re 431 // TODO(martiniss): make this look up request info based on Tree datasto re
420 // object 432 // object
421 req := &monorail.IssuesListRequest{ 433 req := &monorail.IssuesListRequest{
422 ProjectId: tree, 434 ProjectId: tree,
423 Can: monorail.IssuesListRequest_OPEN, 435 Can: monorail.IssuesListRequest_OPEN,
424 Q: fmt.Sprintf("label:Sheriff-%s", tree), 436 Q: fmt.Sprintf("label:Sheriff-%s", tree),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 470
459 m := map[string]string{} 471 m := map[string]string{}
460 err = json.Unmarshal(body, &m) 472 err = json.Unmarshal(body, &m)
461 if err != nil { 473 if err != nil {
462 return nil, err 474 return nil, err
463 } 475 }
464 476
465 return m, nil 477 return m, nil
466 } 478 }
467 479
468 func getRevRangeHandler(c context.Context, w http.ResponseWriter, r *http.Reques t, p httprouter.Params) { 480 func getRevRangeHandler(ctx *router.Context) {
481 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
482
469 start := p.ByName("start") 483 start := p.ByName("start")
470 end := p.ByName("end") 484 end := p.ByName("end")
471 if start == "" || end == "" { 485 if start == "" || end == "" {
472 errStatus(w, http.StatusBadRequest, "Start and end parameters mu st be set.") 486 errStatus(w, http.StatusBadRequest, "Start and end parameters mu st be set.")
473 return 487 return
474 } 488 }
475 489
476 startRev, err := getCrRevJSON(c, start) 490 startRev, err := getCrRevJSON(c, start)
477 if err != nil { 491 if err != nil {
478 errStatus(w, http.StatusInternalServerError, err.Error()) 492 errStatus(w, http.StatusInternalServerError, err.Error())
479 return 493 return
480 } 494 }
481 495
482 endRev, err := getCrRevJSON(c, end) 496 endRev, err := getCrRevJSON(c, end)
483 if err != nil { 497 if err != nil {
484 errStatus(w, http.StatusInternalServerError, err.Error()) 498 errStatus(w, http.StatusInternalServerError, err.Error())
485 return 499 return
486 } 500 }
487 501
488 // TODO(seanmccullough): some sanity checking of the rev json (same repo etc) 502 // TODO(seanmccullough): some sanity checking of the rev json (same repo etc)
489 503
490 gitilesURL := fmt.Sprintf("https://chromium.googlesource.com/chromium/sr c/+log/%s^..%s?format=JSON", 504 gitilesURL := fmt.Sprintf("https://chromium.googlesource.com/chromium/sr c/+log/%s^..%s?format=JSON",
491 startRev["git_sha"], endRev["git_sha"]) 505 startRev["git_sha"], endRev["git_sha"])
492 506
493 http.Redirect(w, r, gitilesURL, 301) 507 http.Redirect(w, r, gitilesURL, 301)
494 } 508 }
495 509
496 // base is the root of the middleware chain. 510 // base is the root of the middleware chain.
497 func base(h middleware.Handler) httprouter.Handle { 511 func base() router.MiddlewareChain {
498 methods := auth.Authenticator{ 512 methods := auth.Authenticator{
499 &server.OAuth2Method{Scopes: []string{server.EmailScope}}, 513 &server.OAuth2Method{Scopes: []string{server.EmailScope}},
500 server.CookieAuth, 514 server.CookieAuth,
501 &server.InboundAppIDAuthMethod{}, 515 &server.InboundAppIDAuthMethod{},
502 } 516 }
503 » h = auth.Use(h, methods) 517 » return append(
504 » if !appengine.IsDevAppServer() { 518 » » gaemiddleware.BaseProd(),
505 » » h = middleware.WithPanicCatcher(h) 519 » » auth.Use(methods),
506 » } 520 » )
507 » return gaemiddleware.BaseProd(h)
508 } 521 }
509 522
510 //// Routes. 523 //// Routes.
511 func init() { 524 func init() {
512 settings.RegisterUIPage(settingsKey, settingsUIPage{}) 525 settings.RegisterUIPage(settingsKey, settingsUIPage{})
513 526
514 » router := httprouter.New() 527 » r := router.New()
515 » gaemiddleware.InstallHandlers(router, base) 528 » basemw := base()
516 » router.GET("/api/v1/trees/", base(auth.Authenticate(getTreesHandler))) 529 » authmw := append(basemw, auth.Authenticate)
517 » router.GET("/api/v1/alerts/:tree", base(auth.Authenticate(getAlertsHandl er)))
518 » router.POST("/api/v1/alerts/:tree", base(auth.Authenticate(postAlertsHan dler)))
519 » router.GET("/api/v1/annotations/", base(auth.Authenticate(getAnnotations Handler)))
520 » router.POST("/api/v1/annotations/:annKey/:action", base(auth.Authenticat e(postAnnotationsHandler)))
521 » router.GET("/api/v1/bugqueue/:tree", base(auth.Authenticate(getBugQueueH andler)))
522 » router.GET("/api/v1/revrange/:start/:end", base(getRevRangeHandler))
523 530
524 » rootRouter := httprouter.New() 531 » gaemiddleware.InstallHandlers(r, basemw)
525 » rootRouter.GET("/*path", base(auth.Authenticate(indexPage))) 532 » r.GET("/api/v1/trees/", authmw, getTreesHandler)
533 » r.GET("/api/v1/alerts/:tree", authmw, getAlertsHandler)
534 » r.POST("/api/v1/alerts/:tree", authmw, postAlertsHandler)
535 » r.GET("/api/v1/annotations/", authmw, getAnnotationsHandler)
536 » r.POST("/api/v1/annotations/:annKey/:action", authmw, postAnnotationsHan dler)
537 » r.GET("/api/v1/bugqueue/:tree", authmw, getBugQueueHandler)
538 » r.GET("/api/v1/revrange/:start/:end", basemw, getRevRangeHandler)
526 539
527 » http.DefaultServeMux.Handle("/api/", router) 540 » rootRouter := router.New()
528 » http.DefaultServeMux.Handle("/admin/", router) 541 » rootRouter.GET("/*path", authmw, indexPage)
529 » http.DefaultServeMux.Handle("/auth/", router) 542
530 » http.DefaultServeMux.Handle("/_ah/", router) 543 » http.DefaultServeMux.Handle("/api/", r)
544 » http.DefaultServeMux.Handle("/admin/", r)
545 » http.DefaultServeMux.Handle("/auth/", r)
546 » http.DefaultServeMux.Handle("/_ah/", r)
531 http.DefaultServeMux.Handle("/", rootRouter) 547 http.DefaultServeMux.Handle("/", rootRouter)
532 } 548 }
OLDNEW
« no previous file with comments | « DEPS ('k') | go/src/infra/appengine/sheriff-o-matic/main_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698