From: Nico Cesar Date: Thu, 21 Jan 2021 19:55:22 +0000 (-0500) Subject: Merge branch '17014-controller-container-requests-take3' X-Git-Tag: 2.2.0~160 X-Git-Url: https://git.arvados.org/arvados.git/commitdiff_plain/4c6c49190b5a8949120d822e053657f64146df70 Merge branch '17014-controller-container-requests-take3' closes #17014 Arvados-DCO-1.1-Signed-off-by: Nico Cesar --- 4c6c49190b5a8949120d822e053657f64146df70 diff --cc lib/controller/integration_test.go index 0e95c19ea5,b240c216cc..3d0639f6cc --- a/lib/controller/integration_test.go +++ b/lib/controller/integration_test.go @@@ -388,10 -488,153 +391,153 @@@ func (s *IntegrationSuite) TestCreateCo req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "OAuth2 "+ac2.AuthToken) resp, err = arvados.InsecureHTTPClient.Do(req) - if c.Check(err, check.IsNil) { - err = json.NewDecoder(resp.Body).Decode(&cr) + c.Assert(err, check.IsNil) + err = json.NewDecoder(resp.Body).Decode(&cr) + c.Check(err, check.IsNil) + c.Check(cr.UUID, check.Matches, "z2222-.*") + } + + func (s *IntegrationSuite) TestCreateContainerRequestWithBadToken(c *check.C) { - conn1 := s.conn("z1111") - rootctx1, _, _ := s.rootClients("z1111") - _, ac1, _, au := s.userClients(rootctx1, c, conn1, "z1111", true) ++ conn1 := s.testClusters["z1111"].Conn() ++ rootctx1, _, _ := s.testClusters["z1111"].RootClients() ++ _, ac1, _, au := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, "user@example.com", true) + + tests := []struct { + name string + token string + expectedCode int + }{ + {"Good token", ac1.AuthToken, http.StatusOK}, + {"Bogus token", "abcdef", http.StatusUnauthorized}, + {"v1-looking token", "badtoken00badtoken00badtoken00badtoken00b", http.StatusUnauthorized}, + {"v2-looking token", "v2/" + au.UUID + "/badtoken00badtoken00badtoken00badtoken00b", http.StatusUnauthorized}, + } + + body, _ := json.Marshal(map[string]interface{}{ + "container_request": map[string]interface{}{ + "command": []string{"echo"}, + "container_image": "d41d8cd98f00b204e9800998ecf8427e+0", + "cwd": "/", + "output_path": "/", + }, + }) + + for _, tt := range tests { + c.Log(c.TestName() + " " + tt.name) + ac1.AuthToken = tt.token + req, err := http.NewRequest("POST", "https://"+ac1.APIHost+"/arvados/v1/container_requests", bytes.NewReader(body)) + c.Assert(err, check.IsNil) + req.Header.Set("Content-Type", "application/json") + resp, err := ac1.Do(req) + c.Assert(err, check.IsNil) + c.Assert(resp.StatusCode, check.Equals, tt.expectedCode) + } + } + + // We test the direct access to the database + // normally an integration test would not have a database access, but in this case we need + // to test tokens that are secret, so there is no API response that will give them back + func (s *IntegrationSuite) dbConn(c *check.C, clusterID string) (*sql.DB, *sql.Conn) { + ctx := context.Background() - db, err := sql.Open("postgres", s.testClusters[clusterID].super.Cluster().PostgreSQL.Connection.String()) ++ db, err := sql.Open("postgres", s.testClusters[clusterID].Super.Cluster().PostgreSQL.Connection.String()) + c.Assert(err, check.IsNil) + + conn, err := db.Conn(ctx) + c.Assert(err, check.IsNil) + + rows, err := conn.ExecContext(ctx, `SELECT 1`) + c.Assert(err, check.IsNil) + n, err := rows.RowsAffected() + c.Assert(err, check.IsNil) + c.Assert(n, check.Equals, int64(1)) + return db, conn + } + + // TestRuntimeTokenInCR will test several different tokens in the runtime attribute + // and check the expected results accessing directly to the database if needed. + func (s *IntegrationSuite) TestRuntimeTokenInCR(c *check.C) { + db, dbconn := s.dbConn(c, "z1111") + defer db.Close() + defer dbconn.Close() - conn1 := s.conn("z1111") - rootctx1, _, _ := s.rootClients("z1111") - userctx1, ac1, _, au := s.userClients(rootctx1, c, conn1, "z1111", true) ++ conn1 := s.testClusters["z1111"].Conn() ++ rootctx1, _, _ := s.testClusters["z1111"].RootClients() ++ userctx1, ac1, _, au := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, "user@example.com", true) + + tests := []struct { + name string + token string + expectAToGetAValidCR bool + expectedToken *string + }{ + {"Good token z1111 user", ac1.AuthToken, true, &ac1.AuthToken}, + {"Bogus token", "abcdef", false, nil}, + {"v1-looking token", "badtoken00badtoken00badtoken00badtoken00b", false, nil}, + {"v2-looking token", "v2/" + au.UUID + "/badtoken00badtoken00badtoken00badtoken00b", false, nil}, + } + + for _, tt := range tests { + c.Log(c.TestName() + " " + tt.name) + + rq := map[string]interface{}{ + "command": []string{"echo"}, + "container_image": "d41d8cd98f00b204e9800998ecf8427e+0", + "cwd": "/", + "output_path": "/", + "runtime_token": tt.token, + } + cr, err := conn1.ContainerRequestCreate(userctx1, arvados.CreateOptions{Attrs: rq}) + if tt.expectAToGetAValidCR { + c.Check(err, check.IsNil) + c.Check(cr, check.NotNil) + c.Check(cr.UUID, check.Not(check.Equals), "") + } + + if tt.expectedToken == nil { + continue + } + + c.Logf("cr.UUID: %s", cr.UUID) + row := dbconn.QueryRowContext(rootctx1, `SELECT runtime_token from container_requests where uuid=$1`, cr.UUID) + c.Check(row, check.NotNil) + var token sql.NullString + row.Scan(&token) + if c.Check(token.Valid, check.Equals, true) { + c.Check(token.String, check.Equals, *tt.expectedToken) + } + } + } + + // TestIntermediateCluster will send a container request to + // one cluster with another cluster as the destination + // and check the tokens are being handled properly + func (s *IntegrationSuite) TestIntermediateCluster(c *check.C) { - conn1 := s.conn("z1111") - rootctx1, _, _ := s.rootClients("z1111") - uctx1, ac1, _, _ := s.userClients(rootctx1, c, conn1, "z1111", true) ++ conn1 := s.testClusters["z1111"].Conn() ++ rootctx1, _, _ := s.testClusters["z1111"].RootClients() ++ uctx1, ac1, _, _ := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, "user@example.com", true) + + tests := []struct { + name string + token string + expectedRuntimeToken string + expectedUUIDprefix string + }{ + {"Good token z1111 user sending a CR to z2222", ac1.AuthToken, "", "z2222-xvhdp-"}, + } + + for _, tt := range tests { + c.Log(c.TestName() + " " + tt.name) + rq := map[string]interface{}{ + "command": []string{"echo"}, + "container_image": "d41d8cd98f00b204e9800998ecf8427e+0", + "cwd": "/", + "output_path": "/", + "runtime_token": tt.token, + } + cr, err := conn1.ContainerRequestCreate(uctx1, arvados.CreateOptions{ClusterID: "z2222", Attrs: rq}) + c.Check(err, check.IsNil) - c.Check(cr.UUID, check.Matches, "z2222-.*") + c.Check(strings.HasPrefix(cr.UUID, tt.expectedUUIDprefix), check.Equals, true) + c.Check(cr.RuntimeToken, check.Equals, tt.expectedRuntimeToken) } }