14287: Merge list results from multiple backends.
[arvados.git] / lib / controller / rpc / conn.go
index 9bb3eb33fb72d17aab6bbee1c54706c254b9b58a..ea3d6fb2dd6e4a537c2a50396f75e02508860c53 100644 (file)
@@ -8,6 +8,7 @@ import (
        "context"
        "crypto/tls"
        "encoding/json"
+       "errors"
        "fmt"
        "io"
        "net"
@@ -17,14 +18,19 @@ import (
        "time"
 
        "git.curoverse.com/arvados.git/sdk/go/arvados"
+       "git.curoverse.com/arvados.git/sdk/go/auth"
 )
 
-type contextKey string
-
-const ContextKeyCredentials contextKey = "credentials"
-
 type TokenProvider func(context.Context) ([]string, error)
 
+func PassthroughTokenProvider(ctx context.Context) ([]string, error) {
+       if incoming, ok := auth.FromContext(ctx); !ok {
+               return nil, errors.New("no token provided")
+       } else {
+               return incoming.Tokens, nil
+       }
+}
+
 type Conn struct {
        clusterID     string
        httpClient    http.Client
@@ -72,13 +78,13 @@ func (conn *Conn) requestAndDecode(ctx context.Context, dst interface{}, ep arva
        if err != nil {
                return err
        } else if len(tokens) > 0 {
-               ctx = context.WithValue(ctx, "Authorization", "Bearer "+tokens[0])
+               ctx = arvados.ContextWithAuthorization(ctx, "Bearer "+tokens[0])
        } else {
                // Use a non-empty auth string to ensure we override
                // any default token set on aClient -- and to avoid
                // having the remote prompt us to send a token by
                // responding 401.
-               ctx = context.WithValue(ctx, "Authorization", "Bearer -")
+               ctx = arvados.ContextWithAuthorization(ctx, "Bearer -")
        }
 
        // Encode opts to JSON and decode from there to a
@@ -103,6 +109,9 @@ func (conn *Conn) requestAndDecode(ctx context.Context, dst interface{}, ep arva
                // remove it entirely.
                delete(params, "limit")
        }
+       if len(tokens) > 1 {
+               params["reader_tokens"] = tokens[1:]
+       }
        path := ep.Path
        if strings.Contains(ep.Path, "/:uuid") {
                uuid, _ := params["uuid"].(string)
@@ -140,6 +149,20 @@ func (conn *Conn) CollectionList(ctx context.Context, options arvados.ListOption
        return resp, err
 }
 
+func (conn *Conn) CollectionProvenance(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error) {
+       ep := arvados.EndpointCollectionProvenance
+       var resp map[string]interface{}
+       err := conn.requestAndDecode(ctx, &resp, ep, nil, options)
+       return resp, err
+}
+
+func (conn *Conn) CollectionUsedBy(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error) {
+       ep := arvados.EndpointCollectionUsedBy
+       var resp map[string]interface{}
+       err := conn.requestAndDecode(ctx, &resp, ep, nil, options)
+       return resp, err
+}
+
 func (conn *Conn) CollectionDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Collection, error) {
        ep := arvados.EndpointCollectionDelete
        var resp arvados.Collection
@@ -147,6 +170,20 @@ func (conn *Conn) CollectionDelete(ctx context.Context, options arvados.DeleteOp
        return resp, err
 }
 
+func (conn *Conn) CollectionTrash(ctx context.Context, options arvados.DeleteOptions) (arvados.Collection, error) {
+       ep := arvados.EndpointCollectionTrash
+       var resp arvados.Collection
+       err := conn.requestAndDecode(ctx, &resp, ep, nil, options)
+       return resp, err
+}
+
+func (conn *Conn) CollectionUntrash(ctx context.Context, options arvados.UntrashOptions) (arvados.Collection, error) {
+       ep := arvados.EndpointCollectionUntrash
+       var resp arvados.Collection
+       err := conn.requestAndDecode(ctx, &resp, ep, nil, options)
+       return resp, err
+}
+
 func (conn *Conn) ContainerCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Container, error) {
        ep := arvados.EndpointContainerCreate
        var resp arvados.Container