package federation
import (
+ "bytes"
"context"
"crypto/md5"
+ "encoding/json"
"errors"
"fmt"
"net/http"
"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"
remotes map[string]backend
}
-func New(cluster *arvados.Cluster) arvados.API {
+func New(cluster *arvados.Cluster) *Conn {
local := railsproxy.NewConn(cluster)
remotes := map[string]backend{}
for id, remote := range cluster.RemoteClusters {
func saltedTokenProvider(local backend, remoteID string) rpc.TokenProvider {
return func(ctx context.Context) ([]string, error) {
var tokens []string
- incoming, ok := ctx.Value(auth.ContextKeyCredentials).(*auth.Credentials)
+ incoming, ok := auth.FromContext(ctx)
if !ok {
return nil, errors.New("no token provided")
}
case auth.ErrSalted:
tokens = append(tokens, token)
case auth.ErrObsoleteToken:
- ctx := context.WithValue(ctx, auth.ContextKeyCredentials, &auth.Credentials{Tokens: []string{token}})
+ ctx := auth.NewContext(ctx, &auth.Credentials{Tokens: []string{token}})
aca, err := local.APIClientAuthorizationCurrent(ctx, arvados.GetOptions{})
if errStatus(err) == http.StatusUnauthorized {
// pass through unmodified
// Return suitable backend for a query about the given cluster ID
// ("aaaaa") or object UUID ("aaaaa-dz642-abcdefghijklmno").
func (conn *Conn) chooseBackend(id string) backend {
- if len(id) > 5 {
+ if len(id) == 27 {
id = id[:5]
+ } else if len(id) != 5 {
+ // PDH or bogus ID
+ return conn.local
}
if id == conn.cluster.ClusterID {
return conn.local
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
}
}
-func (conn *Conn) CollectionList(ctx context.Context, options arvados.ListOptions) (arvados.CollectionList, error) {
- return conn.local.CollectionList(ctx, options)
-}
-
func (conn *Conn) CollectionProvenance(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error) {
- return conn.local.CollectionProvenance(ctx, options)
+ return conn.chooseBackend(options.UUID).CollectionProvenance(ctx, options)
}
func (conn *Conn) CollectionUsedBy(ctx context.Context, options arvados.GetOptions) (map[string]interface{}, error) {
- return conn.local.CollectionUsedBy(ctx, options)
+ return conn.chooseBackend(options.UUID).CollectionUsedBy(ctx, options)
}
func (conn *Conn) CollectionDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Collection, error) {
return conn.chooseBackend(options.UUID).ContainerGet(ctx, options)
}
-func (conn *Conn) ContainerList(ctx context.Context, options arvados.ListOptions) (arvados.ContainerList, error) {
- return conn.local.ContainerList(ctx, options)
-}
-
func (conn *Conn) ContainerDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Container, error) {
return conn.chooseBackend(options.UUID).ContainerDelete(ctx, options)
}
return conn.chooseBackend(options.UUID).SpecimenGet(ctx, options)
}
-func (conn *Conn) SpecimenList(ctx context.Context, options arvados.ListOptions) (arvados.SpecimenList, error) {
- return conn.local.SpecimenList(ctx, options)
-}
-
func (conn *Conn) SpecimenDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Specimen, error) {
return conn.chooseBackend(options.UUID).SpecimenDelete(ctx, options)
}