1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
19 "git.curoverse.com/arvados.git/sdk/go/arvados"
20 "git.curoverse.com/arvados.git/sdk/go/arvadostest"
21 "git.curoverse.com/arvados.git/sdk/go/auth"
22 "git.curoverse.com/arvados.git/sdk/go/keepclient"
23 check "gopkg.in/check.v1"
26 var _ = check.Suite(&ProxyRemoteSuite{})
28 type ProxyRemoteSuite struct {
29 cluster *arvados.Cluster
33 remoteClusterID string
34 remoteBlobSigningKey []byte
35 remoteKeepLocator string
37 remoteKeepproxy *httptest.Server
38 remoteKeepRequests int64
39 remoteAPI *httptest.Server
42 func (s *ProxyRemoteSuite) remoteKeepproxyHandler(w http.ResponseWriter, r *http.Request) {
43 expectToken, err := auth.SaltToken(arvadostest.ActiveTokenV2, s.remoteClusterID)
47 atomic.AddInt64(&s.remoteKeepRequests, 1)
49 if auth := strings.Split(r.Header.Get("Authorization"), " "); len(auth) == 2 && (auth[0] == "OAuth2" || auth[0] == "Bearer") {
52 if r.Method == "GET" && r.URL.Path == "/"+s.remoteKeepLocator && token == expectToken {
53 w.Write(s.remoteKeepData)
56 http.Error(w, "404", 404)
59 func (s *ProxyRemoteSuite) remoteAPIHandler(w http.ResponseWriter, r *http.Request) {
60 host, port, _ := net.SplitHostPort(strings.Split(s.remoteKeepproxy.URL, "//")[1])
61 portnum, _ := strconv.Atoi(port)
62 if r.URL.Path == "/arvados/v1/discovery/v1/rest" {
63 json.NewEncoder(w).Encode(arvados.DiscoveryDocument{})
66 if r.URL.Path == "/arvados/v1/keep_services/accessible" {
67 json.NewEncoder(w).Encode(arvados.KeepServiceList{
68 Items: []arvados.KeepService{
70 UUID: s.remoteClusterID + "-bi6l4-proxyproxyproxy",
74 ServiceSSLFlag: false,
80 http.Error(w, "404", 404)
83 func (s *ProxyRemoteSuite) SetUpTest(c *check.C) {
84 s.remoteClusterID = "z0000"
85 s.remoteBlobSigningKey = []byte("3b6df6fb6518afe12922a5bc8e67bf180a358bc8")
86 s.remoteKeepproxy = httptest.NewServer(http.HandlerFunc(s.remoteKeepproxyHandler))
87 s.remoteAPI = httptest.NewUnstartedServer(http.HandlerFunc(s.remoteAPIHandler))
88 s.remoteAPI.StartTLS()
89 s.cluster = arvados.IntegrationTestCluster()
90 s.cluster.RemoteClusters = map[string]arvados.RemoteCluster{
91 s.remoteClusterID: arvados.RemoteCluster{
92 Host: strings.Split(s.remoteAPI.URL, "//")[1],
98 s.vm = MakeTestVolumeManager(2)
100 theConfig = DefaultConfig()
101 theConfig.systemAuthToken = arvadostest.DataManagerToken
103 s.rtr = MakeRESTRouter(s.cluster)
106 func (s *ProxyRemoteSuite) TearDownTest(c *check.C) {
109 theConfig = DefaultConfig()
112 s.remoteKeepproxy.Close()
115 func (s *ProxyRemoteSuite) TestProxyRemote(c *check.C) {
116 data := []byte("foo bar")
117 s.remoteKeepData = data
118 locator := fmt.Sprintf("%x+%d", md5.Sum(data), len(data))
119 s.remoteKeepLocator = keepclient.SignLocator(locator, arvadostest.ActiveTokenV2, time.Now().Add(time.Minute), time.Minute, s.remoteBlobSigningKey)
121 path := "/" + strings.Replace(s.remoteKeepLocator, "+A", "+R"+s.remoteClusterID+"-", 1)
123 var req *http.Request
124 var resp *httptest.ResponseRecorder
125 tryWithToken := func(token string) {
126 req = httptest.NewRequest("GET", path, nil)
127 req.Header.Set("Authorization", "Bearer "+token)
128 resp = httptest.NewRecorder()
129 s.rtr.ServeHTTP(resp, req)
133 tryWithToken(arvadostest.ActiveTokenV2)
134 c.Check(s.remoteKeepRequests, check.Equals, int64(1))
135 c.Check(resp.Code, check.Equals, http.StatusOK)
136 c.Check(resp.Body.String(), check.Equals, string(data))
139 tryWithToken(arvadostest.ActiveToken)
140 c.Check(s.remoteKeepRequests, check.Equals, int64(1))
141 c.Check(resp.Code, check.Equals, http.StatusBadRequest)
142 c.Check(resp.Body.String(), check.Not(check.Equals), string(data))
145 tryWithToken(arvadostest.ActiveTokenV2[:len(arvadostest.ActiveTokenV2)-3] + "xxx")
146 c.Check(s.remoteKeepRequests, check.Equals, int64(2))
147 c.Check(resp.Code, check.Equals, http.StatusNotFound)
148 c.Check(resp.Body.String(), check.Not(check.Equals), string(data))