14813: Add CORS headers to "get config" by moving it to arvados.API.
authorTom Clegg <tclegg@veritasgenetics.com>
Wed, 24 Jul 2019 13:43:18 +0000 (09:43 -0400)
committerTom Clegg <tclegg@veritasgenetics.com>
Thu, 25 Jul 2019 13:39:49 +0000 (09:39 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

lib/controller/federation/conn.go
lib/controller/handler.go
lib/controller/handler_test.go
lib/controller/router/router.go
lib/controller/rpc/conn.go
sdk/go/arvados/api.go
sdk/go/arvadostest/api.go

index 3addcf4fa91fac63e622870000e32f0d6d260459..63e801b22c7a2bebd5a6a35fdefa4835c1775c1d 100644 (file)
@@ -5,8 +5,10 @@
 package federation
 
 import (
+       "bytes"
        "context"
        "crypto/md5"
+       "encoding/json"
        "errors"
        "fmt"
        "net/http"
@@ -14,6 +16,7 @@ import (
        "regexp"
        "strings"
 
+       "git.curoverse.com/arvados.git/lib/config"
        "git.curoverse.com/arvados.git/lib/controller/railsproxy"
        "git.curoverse.com/arvados.git/lib/controller/rpc"
        "git.curoverse.com/arvados.git/sdk/go/arvados"
@@ -177,6 +180,12 @@ func portableDataHash(mt string) string {
        return fmt.Sprintf("%x+%d", h.Sum(nil), size)
 }
 
+func (conn *Conn) ConfigGet(ctx context.Context) (json.RawMessage, error) {
+       var buf bytes.Buffer
+       err := config.ExportJSON(&buf, conn.cluster)
+       return json.RawMessage(buf.Bytes()), err
+}
+
 func (conn *Conn) CollectionGet(ctx context.Context, options arvados.GetOptions) (arvados.Collection, error) {
        if len(options.UUID) == 27 {
                // UUID is really a UUID
index 852327fd89f04a2b9c67d2238e6e47219e6565ca..f7b2362f371e71b99a196d4b795e54a927e81919 100644 (file)
@@ -5,19 +5,16 @@
 package controller
 
 import (
-       "bytes"
        "context"
        "database/sql"
        "errors"
        "fmt"
-       "io"
        "net/http"
        "net/url"
        "strings"
        "sync"
        "time"
 
-       "git.curoverse.com/arvados.git/lib/config"
        "git.curoverse.com/arvados.git/lib/controller/federation"
        "git.curoverse.com/arvados.git/lib/controller/railsproxy"
        "git.curoverse.com/arvados.git/lib/controller/router"
@@ -80,19 +77,10 @@ func (h *Handler) setup() {
                Routes: health.Routes{"ping": func() error { _, err := h.db(&http.Request{}); return err }},
        })
 
-       mux.Handle("/arvados/v1/config", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-               var buf bytes.Buffer
-               err := config.ExportJSON(&buf, h.Cluster)
-               if err != nil {
-                       httpserver.Error(w, err.Error(), http.StatusInternalServerError)
-                       return
-               }
-               w.Header().Set("Content-Type", "application/json")
-               io.Copy(w, &buf)
-       }))
+       rtr := router.New(federation.New(h.Cluster))
+       mux.Handle("/arvados/v1/config", rtr)
 
        if h.Cluster.EnableBetaController14287 {
-               rtr := router.New(federation.New(h.Cluster))
                mux.Handle("/arvados/v1/collections", rtr)
                mux.Handle("/arvados/v1/collections/", rtr)
        }
index fbfb037d36dad0d4716c3422c452aec0a118049b..4b49e46154e24b057ba5750c21f9f47e4541d7ae 100644 (file)
@@ -68,6 +68,9 @@ func (s *HandlerSuite) TestConfigExport(c *check.C) {
        resp := httptest.NewRecorder()
        s.handler.ServeHTTP(resp, req)
        c.Check(resp.Code, check.Equals, http.StatusOK)
+       c.Check(resp.Header().Get("Access-Control-Allow-Origin"), check.Equals, `*`)
+       c.Check(resp.Header().Get("Access-Control-Allow-Methods"), check.Matches, `.*\bGET\b.*`)
+       c.Check(resp.Header().Get("Access-Control-Allow-Headers"), check.Matches, `.+`)
        var cluster arvados.Cluster
        c.Log(resp.Body.String())
        err := json.Unmarshal(resp.Body.Bytes(), &cluster)
index 9c2c1f3a11f6dac93eeabeb6478bea8653b9aedb..5d5602df523b672d6e8f6d84346ed5255a20ae76 100644 (file)
@@ -40,6 +40,13 @@ func (rtr *router) addRoutes() {
                defaultOpts func() interface{}
                exec        routableFunc
        }{
+               {
+                       arvados.EndpointConfigGet,
+                       func() interface{} { return &struct{}{} },
+                       func(ctx context.Context, opts interface{}) (interface{}, error) {
+                               return rtr.fed.ConfigGet(ctx)
+                       },
+               },
                {
                        arvados.EndpointCollectionCreate,
                        func() interface{} { return &arvados.CreateOptions{} },
index ea3d6fb2dd6e4a537c2a50396f75e02508860c53..1028da829fbdb0361fc5b041e98fba5e30c81c6c 100644 (file)
@@ -121,6 +121,13 @@ func (conn *Conn) requestAndDecode(ctx context.Context, dst interface{}, ep arva
        return aClient.RequestAndDecodeContext(ctx, dst, ep.Method, path, body, params)
 }
 
+func (conn *Conn) ConfigGet(ctx context.Context) (json.RawMessage, error) {
+       ep := arvados.EndpointConfigGet
+       var resp json.RawMessage
+       err := conn.requestAndDecode(ctx, &resp, ep, nil, nil)
+       return resp, err
+}
+
 func (conn *Conn) CollectionCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Collection, error) {
        ep := arvados.EndpointCollectionCreate
        var resp arvados.Collection
index 71265756da9f4c691235efd80bdab35dba22fc3c..772f8da9719ae874d3f392782fb6388d3e74a488 100644 (file)
@@ -4,7 +4,10 @@
 
 package arvados
 
-import "context"
+import (
+       "context"
+       "encoding/json"
+)
 
 type APIEndpoint struct {
        Method string
@@ -14,6 +17,7 @@ type APIEndpoint struct {
 }
 
 var (
+       EndpointConfigGet                     = APIEndpoint{"GET", "arvados/v1/config", ""}
        EndpointCollectionCreate              = APIEndpoint{"POST", "arvados/v1/collections", "collection"}
        EndpointCollectionUpdate              = APIEndpoint{"PATCH", "arvados/v1/collections/:uuid", "collection"}
        EndpointCollectionGet                 = APIEndpoint{"GET", "arvados/v1/collections/:uuid", ""}
@@ -80,6 +84,7 @@ type DeleteOptions struct {
 }
 
 type API interface {
+       ConfigGet(ctx context.Context) (json.RawMessage, error)
        CollectionCreate(ctx context.Context, options CreateOptions) (Collection, error)
        CollectionUpdate(ctx context.Context, options UpdateOptions) (Collection, error)
        CollectionGet(ctx context.Context, options GetOptions) (Collection, error)
index 77a26bcba75526771cdd623a42270f8646f721a4..850bd0639dcaa856c5b6dfa69b09309a1ead1de5 100644 (file)
@@ -6,6 +6,7 @@ package arvadostest
 
 import (
        "context"
+       "encoding/json"
        "errors"
        "reflect"
        "runtime"
@@ -23,6 +24,10 @@ type APIStub struct {
        mtx   sync.Mutex
 }
 
+func (as *APIStub) ConfigGet(ctx context.Context) (json.RawMessage, error) {
+       as.appendCall(as.ConfigGet, ctx, nil)
+       return nil, as.Error
+}
 func (as *APIStub) CollectionCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Collection, error) {
        as.appendCall(as.CollectionCreate, ctx, options)
        return arvados.Collection{}, as.Error