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 for _, trial := range []struct {
126 expectRemoteReqs int64
131 token: arvadostest.ActiveTokenV2,
133 expectCode: http.StatusOK,
136 label: "obsolete token",
137 token: arvadostest.ActiveToken,
139 expectCode: http.StatusBadRequest,
143 token: arvadostest.ActiveTokenV2[:len(arvadostest.ActiveTokenV2)-3] + "xxx",
145 expectCode: http.StatusNotFound,
148 c.Logf("trial: %s", trial.label)
150 s.remoteKeepRequests = 0
152 var req *http.Request
153 var resp *httptest.ResponseRecorder
154 req = httptest.NewRequest("GET", path, nil)
155 req.Header.Set("Authorization", "Bearer "+trial.token)
156 resp = httptest.NewRecorder()
157 s.rtr.ServeHTTP(resp, req)
158 c.Check(s.remoteKeepRequests, check.Equals, trial.expectRemoteReqs)
159 c.Check(resp.Code, check.Equals, trial.expectCode)
160 if resp.Code == http.StatusOK {
161 c.Check(resp.Body.String(), check.Equals, string(data))
163 c.Check(resp.Body.String(), check.Not(check.Equals), string(data))