[ARVADOS] created: 2.1.0-243-g59e8b47be
Git user
git at public.arvados.org
Fri Jan 8 15:25:48 UTC 2021
at 59e8b47bee1c9699cbb2d16369481bd688da6e3d (commit)
commit 59e8b47bee1c9699cbb2d16369481bd688da6e3d
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date: Fri Jan 8 12:24:14 2021 -0300
16981: Adds federation test on sync-groups.
Makes sure that running the tool on a federated cluster with admin credentials
from the LoginCluster works correctly.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>
diff --git a/lib/controller/integration_test.go b/lib/controller/integration_test.go
index 33c68ce6e..7e719e72e 100644
--- a/lib/controller/integration_test.go
+++ b/lib/controller/integration_test.go
@@ -74,8 +74,6 @@ func (s *IntegrationSuite) SetUpSuite(c *check.C) {
ExternalURL: https://` + hostport[id] + `
TLS:
Insecure: true
- Login:
- LoginCluster: z1111
SystemLogs:
Format: text
RemoteClusters:
diff --git a/sdk/go/arvadostest/federation_servers.go b/sdk/go/arvadostest/test_cluster.go
similarity index 100%
rename from sdk/go/arvadostest/federation_servers.go
rename to sdk/go/arvadostest/test_cluster.go
diff --git a/tools/sync-groups/federation_test.go b/tools/sync-groups/federation_test.go
new file mode 100644
index 000000000..2462383f3
--- /dev/null
+++ b/tools/sync-groups/federation_test.go
@@ -0,0 +1,202 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+package main
+
+import (
+ "net"
+ "os"
+ "path/filepath"
+
+ "git.arvados.org/arvados.git/sdk/go/arvados"
+ "git.arvados.org/arvados.git/sdk/go/arvadostest"
+ check "gopkg.in/check.v1"
+)
+
+var _ = check.Suite(&FederationSuite{})
+
+var origAPIHost, origAPIToken string
+
+type FederationSuite struct {
+ testClusters map[string]*arvadostest.TestCluster
+ oidcprovider *arvadostest.OIDCProvider
+}
+
+func (s *FederationSuite) SetUpSuite(c *check.C) {
+ origAPIHost = os.Getenv("ARVADOS_API_HOST")
+ origAPIToken = os.Getenv("ARVADOS_API_TOKEN")
+
+ cwd, _ := os.Getwd()
+
+ s.oidcprovider = arvadostest.NewOIDCProvider(c)
+ s.oidcprovider.AuthEmail = "user at example.com"
+ s.oidcprovider.AuthEmailVerified = true
+ s.oidcprovider.AuthName = "Example User"
+ s.oidcprovider.ValidClientID = "clientid"
+ s.oidcprovider.ValidClientSecret = "clientsecret"
+
+ s.testClusters = map[string]*arvadostest.TestCluster{
+ "z1111": nil,
+ "z2222": nil,
+ }
+ hostport := map[string]string{}
+ for id := range s.testClusters {
+ hostport[id] = func() string {
+ // TODO: Instead of expecting random ports on
+ // 127.0.0.11, 22 to be race-safe, try
+ // different 127.x.y.z until finding one that
+ // isn't in use.
+ ln, err := net.Listen("tcp", ":0")
+ c.Assert(err, check.IsNil)
+ ln.Close()
+ _, port, err := net.SplitHostPort(ln.Addr().String())
+ c.Assert(err, check.IsNil)
+ return "127.0.0." + id[3:] + ":" + port
+ }()
+ }
+ for id := range s.testClusters {
+ yaml := `Clusters:
+ ` + id + `:
+ Services:
+ Controller:
+ ExternalURL: https://` + hostport[id] + `
+ TLS:
+ Insecure: true
+ SystemLogs:
+ Format: text
+ RemoteClusters:
+ z1111:
+ Host: ` + hostport["z1111"] + `
+ Scheme: https
+ Insecure: true
+ Proxy: true
+ ActivateUsers: true
+`
+ if id != "z2222" {
+ yaml += ` z2222:
+ Host: ` + hostport["z2222"] + `
+ Scheme: https
+ Insecure: true
+ Proxy: true
+ ActivateUsers: true
+`
+ }
+ if id == "z1111" {
+ yaml += `
+ Login:
+ LoginCluster: z1111
+ OpenIDConnect:
+ Enable: true
+ Issuer: ` + s.oidcprovider.Issuer.URL + `
+ ClientID: ` + s.oidcprovider.ValidClientID + `
+ ClientSecret: ` + s.oidcprovider.ValidClientSecret + `
+ EmailClaim: email
+ EmailVerifiedClaim: email_verified
+`
+ } else {
+ yaml += `
+ Login:
+ LoginCluster: z1111
+`
+ }
+
+ tc, err := arvadostest.NewTestCluster(
+ filepath.Join(cwd, "..", ".."),
+ id, yaml, "127.0.0."+id[3:], c.Log)
+ c.Assert(err, check.IsNil)
+ s.testClusters[id] = tc
+ s.testClusters[id].Start()
+ }
+ for _, tc := range s.testClusters {
+ ok := tc.WaitReady()
+ c.Assert(ok, check.Equals, true)
+ }
+
+ // Activate user, make it admin.
+ conn1 := s.testClusters["z1111"].Conn()
+ rootctx1, _, _ := s.testClusters["z1111"].RootClients()
+ userctx1, _, _, _ := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, s.oidcprovider.AuthEmail, true)
+ user1, err := conn1.UserGetCurrent(userctx1, arvados.GetOptions{})
+ c.Assert(err, check.IsNil)
+ c.Assert(user1.IsAdmin, check.Equals, false)
+ user1, err = conn1.UserUpdate(rootctx1, arvados.UpdateOptions{
+ UUID: user1.UUID,
+ Attrs: map[string]interface{}{
+ "is_admin": true,
+ },
+ })
+ c.Assert(err, check.IsNil)
+ c.Assert(user1.IsAdmin, check.Equals, true)
+}
+
+func (s *FederationSuite) TearDownSuite(c *check.C) {
+ for _, c := range s.testClusters {
+ c.Super.Stop()
+ }
+ _ = os.Setenv("ARVADOS_API_HOST", origAPIHost)
+ _ = os.Setenv("ARVADOS_API_TOKEN", origAPIToken)
+}
+
+func (s *FederationSuite) TestGroupSyncingOnFederatedCluster(c *check.C) {
+ // Get admin user's V2 token
+ conn1 := s.testClusters["z1111"].Conn()
+ rootctx1, _, _ := s.testClusters["z1111"].RootClients()
+ userctx1, _, _, _ := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, s.oidcprovider.AuthEmail, true)
+ user1Auth, err := conn1.APIClientAuthorizationCurrent(userctx1, arvados.GetOptions{})
+ c.Check(err, check.IsNil)
+ userV2Token := user1Auth.TokenV2()
+
+ // Get federated admin clients on z2222 to set up environment
+ conn2 := s.testClusters["z2222"].Conn()
+ userctx2, userac2, _ := s.testClusters["z2222"].ClientsWithToken(userV2Token)
+ user2, err := conn2.UserGetCurrent(userctx2, arvados.GetOptions{})
+ c.Check(err, check.IsNil)
+ c.Check(user2.IsAdmin, check.Equals, true)
+
+ // Set up environment for sync-groups using admin user credentials on z2222
+ err = os.Setenv("ARVADOS_API_HOST", userac2.APIHost)
+ c.Assert(err, check.IsNil)
+ err = os.Setenv("ARVADOS_API_TOKEN", userac2.AuthToken)
+ c.Assert(err, check.IsNil)
+
+ // Check that no parent group is created
+ gl := arvados.GroupList{}
+ params := arvados.ResourceListParams{
+ Filters: []arvados.Filter{{
+ Attr: "owner_uuid",
+ Operator: "=",
+ Operand: s.testClusters["z2222"].ClusterID + "-tpzed-000000000000000",
+ }, {
+ Attr: "name",
+ Operator: "=",
+ Operand: "Externally synchronized groups",
+ }},
+ }
+ err = userac2.RequestAndDecode(&gl, "GET", "/arvados/v1/groups", nil, params)
+ c.Assert(err, check.IsNil)
+ c.Assert(gl.ItemsAvailable, check.Equals, 0)
+
+ // Set up config, confirm that the parent group was created
+ os.Args = []string{"cmd", "somefile.csv"}
+ config, err := GetConfig()
+ c.Assert(err, check.IsNil)
+ userac2.RequestAndDecode(&gl, "GET", "/arvados/v1/groups", nil, params)
+ c.Assert(gl.ItemsAvailable, check.Equals, 1)
+
+ // Run the tool with custom config
+ data := [][]string{
+ {"TestGroup1", user2.Email},
+ }
+ tmpfile, err := MakeTempCSVFile(data)
+ c.Assert(err, check.IsNil)
+ defer os.Remove(tmpfile.Name()) // clean up
+ config.Path = tmpfile.Name()
+ err = doMain(&config)
+ c.Assert(err, check.IsNil)
+ // Check the group was created correctly, and has the user as a member
+ groupUUID, err := RemoteGroupExists(&config, "TestGroup1")
+ c.Assert(err, check.IsNil)
+ c.Assert(groupUUID, check.Not(check.Equals), "")
+ c.Assert(GroupMembershipExists(config.Client, user2.UUID, groupUUID, "can_write"), check.Equals, true)
+}
commit cc45e3eb3609af1fd3b186e3aa6e806bcf1e92ae
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date: Tue Jan 5 17:40:27 2021 -0300
16981: Extracts test federation building code to the arvadostest package.
This is going to be reused on other integration test suites.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>
diff --git a/lib/controller/integration_test.go b/lib/controller/integration_test.go
index 0388f21be..33c68ce6e 100644
--- a/lib/controller/integration_test.go
+++ b/lib/controller/integration_test.go
@@ -6,7 +6,6 @@ package controller
import (
"bytes"
- "context"
"encoding/json"
"fmt"
"io"
@@ -14,36 +13,21 @@ import (
"math"
"net"
"net/http"
- "net/url"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
- "git.arvados.org/arvados.git/lib/boot"
- "git.arvados.org/arvados.git/lib/config"
- "git.arvados.org/arvados.git/lib/controller/rpc"
- "git.arvados.org/arvados.git/lib/service"
"git.arvados.org/arvados.git/sdk/go/arvados"
- "git.arvados.org/arvados.git/sdk/go/arvadosclient"
"git.arvados.org/arvados.git/sdk/go/arvadostest"
- "git.arvados.org/arvados.git/sdk/go/auth"
- "git.arvados.org/arvados.git/sdk/go/ctxlog"
- "git.arvados.org/arvados.git/sdk/go/keepclient"
check "gopkg.in/check.v1"
)
var _ = check.Suite(&IntegrationSuite{})
-type testCluster struct {
- super boot.Supervisor
- config arvados.Config
- controllerURL *url.URL
-}
-
type IntegrationSuite struct {
- testClusters map[string]*testCluster
+ testClusters map[string]*arvadostest.TestCluster
oidcprovider *arvadostest.OIDCProvider
}
@@ -62,7 +46,7 @@ func (s *IntegrationSuite) SetUpSuite(c *check.C) {
s.oidcprovider.ValidClientID = "clientid"
s.oidcprovider.ValidClientSecret = "clientsecret"
- s.testClusters = map[string]*testCluster{
+ s.testClusters = map[string]*arvadostest.TestCluster{
"z1111": nil,
"z2222": nil,
"z3333": nil,
@@ -139,118 +123,30 @@ func (s *IntegrationSuite) SetUpSuite(c *check.C) {
`
}
- loader := config.NewLoader(bytes.NewBufferString(yaml), ctxlog.TestLogger(c))
- loader.Path = "-"
- loader.SkipLegacy = true
- loader.SkipAPICalls = true
- cfg, err := loader.Load()
+ tc, err := arvadostest.NewTestCluster(
+ filepath.Join(cwd, "..", ".."),
+ id, yaml, "127.0.0."+id[3:], c.Log)
c.Assert(err, check.IsNil)
- s.testClusters[id] = &testCluster{
- super: boot.Supervisor{
- SourcePath: filepath.Join(cwd, "..", ".."),
- ClusterType: "test",
- ListenHost: "127.0.0." + id[3:],
- ControllerAddr: ":0",
- OwnTemporaryDatabase: true,
- Stderr: &service.LogPrefixer{Writer: ctxlog.LogWriter(c.Log), Prefix: []byte("[" + id + "] ")},
- },
- config: *cfg,
- }
- s.testClusters[id].super.Start(context.Background(), &s.testClusters[id].config, "-")
+ s.testClusters[id] = tc
+ s.testClusters[id].Start()
}
for _, tc := range s.testClusters {
- au, ok := tc.super.WaitReady()
+ ok := tc.WaitReady()
c.Assert(ok, check.Equals, true)
- u := url.URL(*au)
- tc.controllerURL = &u
}
}
func (s *IntegrationSuite) TearDownSuite(c *check.C) {
for _, c := range s.testClusters {
- c.super.Stop()
+ c.Super.Stop()
}
}
-// Get rpc connection struct initialized to communicate with the
-// specified cluster.
-func (s *IntegrationSuite) conn(clusterID string) *rpc.Conn {
- return rpc.NewConn(clusterID, s.testClusters[clusterID].controllerURL, true, rpc.PassthroughTokenProvider)
-}
-
-// Return Context, Arvados.Client and keepclient structs initialized
-// to connect to the specified cluster (by clusterID) using with the supplied
-// Arvados token.
-func (s *IntegrationSuite) clientsWithToken(clusterID string, token string) (context.Context, *arvados.Client, *keepclient.KeepClient) {
- cl := s.testClusters[clusterID].config.Clusters[clusterID]
- ctx := auth.NewContext(context.Background(), auth.NewCredentials(token))
- ac, err := arvados.NewClientFromConfig(&cl)
- if err != nil {
- panic(err)
- }
- ac.AuthToken = token
- arv, err := arvadosclient.New(ac)
- if err != nil {
- panic(err)
- }
- kc := keepclient.New(arv)
- return ctx, ac, kc
-}
-
-// Log in as a user called "example", get the user's API token,
-// initialize clients with the API token, set up the user and
-// optionally activate the user. Return client structs for
-// communicating with the cluster on behalf of the 'example' user.
-func (s *IntegrationSuite) userClients(rootctx context.Context, c *check.C, conn *rpc.Conn, clusterID string, activate bool) (context.Context, *arvados.Client, *keepclient.KeepClient, arvados.User) {
- login, err := conn.UserSessionCreate(rootctx, rpc.UserSessionCreateOptions{
- ReturnTo: ",https://example.com",
- AuthInfo: rpc.UserSessionAuthInfo{
- Email: "user at example.com",
- FirstName: "Example",
- LastName: "User",
- Username: "example",
- },
- })
- c.Assert(err, check.IsNil)
- redirURL, err := url.Parse(login.RedirectLocation)
- c.Assert(err, check.IsNil)
- userToken := redirURL.Query().Get("api_token")
- c.Logf("user token: %q", userToken)
- ctx, ac, kc := s.clientsWithToken(clusterID, userToken)
- user, err := conn.UserGetCurrent(ctx, arvados.GetOptions{})
- c.Assert(err, check.IsNil)
- _, err = conn.UserSetup(rootctx, arvados.UserSetupOptions{UUID: user.UUID})
- c.Assert(err, check.IsNil)
- if activate {
- _, err = conn.UserActivate(rootctx, arvados.UserActivateOptions{UUID: user.UUID})
- c.Assert(err, check.IsNil)
- user, err = conn.UserGetCurrent(ctx, arvados.GetOptions{})
- c.Assert(err, check.IsNil)
- c.Logf("user UUID: %q", user.UUID)
- if !user.IsActive {
- c.Fatalf("failed to activate user -- %#v", user)
- }
- }
- return ctx, ac, kc, user
-}
-
-// Return Context, arvados.Client and keepclient structs initialized
-// to communicate with the cluster as the system root user.
-func (s *IntegrationSuite) rootClients(clusterID string) (context.Context, *arvados.Client, *keepclient.KeepClient) {
- return s.clientsWithToken(clusterID, s.testClusters[clusterID].config.Clusters[clusterID].SystemRootToken)
-}
-
-// Return Context, arvados.Client and keepclient structs initialized
-// to communicate with the cluster as the anonymous user.
-func (s *IntegrationSuite) anonymousClients(clusterID string) (context.Context, *arvados.Client, *keepclient.KeepClient) {
- return s.clientsWithToken(clusterID, s.testClusters[clusterID].config.Clusters[clusterID].Users.AnonymousUserToken)
-}
-
func (s *IntegrationSuite) TestGetCollectionByPDH(c *check.C) {
- conn1 := s.conn("z1111")
- rootctx1, _, _ := s.rootClients("z1111")
- conn3 := s.conn("z3333")
- userctx1, ac1, kc1, _ := s.userClients(rootctx1, c, conn1, "z1111", true)
+ conn1 := s.testClusters["z1111"].Conn()
+ rootctx1, _, _ := s.testClusters["z1111"].RootClients()
+ conn3 := s.testClusters["z3333"].Conn()
+ userctx1, ac1, kc1, _ := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, s.oidcprovider.AuthEmail, true)
// Create the collection to find its PDH (but don't save it
// anywhere yet)
@@ -292,13 +188,13 @@ func (s *IntegrationSuite) TestS3WithFederatedToken(c *check.C) {
testText := "IntegrationSuite.TestS3WithFederatedToken"
- conn1 := s.conn("z1111")
- rootctx1, _, _ := s.rootClients("z1111")
- userctx1, ac1, _, _ := s.userClients(rootctx1, c, conn1, "z1111", true)
- conn3 := s.conn("z3333")
+ conn1 := s.testClusters["z1111"].Conn()
+ rootctx1, _, _ := s.testClusters["z1111"].RootClients()
+ userctx1, ac1, _, _ := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, s.oidcprovider.AuthEmail, true)
+ conn3 := s.testClusters["z3333"].Conn()
createColl := func(clusterID string) arvados.Collection {
- _, ac, kc := s.clientsWithToken(clusterID, ac1.AuthToken)
+ _, ac, kc := s.testClusters[clusterID].ClientsWithToken(ac1.AuthToken)
var coll arvados.Collection
fs, err := coll.FileSystem(ac, kc)
c.Assert(err, check.IsNil)
@@ -310,7 +206,7 @@ func (s *IntegrationSuite) TestS3WithFederatedToken(c *check.C) {
c.Assert(err, check.IsNil)
mtxt, err := fs.MarshalManifest(".")
c.Assert(err, check.IsNil)
- coll, err = s.conn(clusterID).CollectionCreate(userctx1, arvados.CreateOptions{Attrs: map[string]interface{}{
+ coll, err = s.testClusters[clusterID].Conn().CollectionCreate(userctx1, arvados.CreateOptions{Attrs: map[string]interface{}{
"manifest_text": mtxt,
}})
c.Assert(err, check.IsNil)
@@ -358,10 +254,10 @@ func (s *IntegrationSuite) TestS3WithFederatedToken(c *check.C) {
}
func (s *IntegrationSuite) TestGetCollectionAsAnonymous(c *check.C) {
- conn1 := s.conn("z1111")
- conn3 := s.conn("z3333")
- rootctx1, rootac1, rootkc1 := s.rootClients("z1111")
- anonctx3, anonac3, _ := s.anonymousClients("z3333")
+ conn1 := s.testClusters["z1111"].Conn()
+ conn3 := s.testClusters["z3333"].Conn()
+ rootctx1, rootac1, rootkc1 := s.testClusters["z1111"].RootClients()
+ anonctx3, anonac3, _ := s.testClusters["z3333"].AnonymousClients()
// Make sure anonymous token was set
c.Assert(anonac3.AuthToken, check.Not(check.Equals), "")
@@ -410,7 +306,7 @@ func (s *IntegrationSuite) TestGetCollectionAsAnonymous(c *check.C) {
c.Check(err, check.IsNil)
// Make a v2 token of the z3 anonymous user, and use it on z1
- _, anonac1, _ := s.clientsWithToken("z1111", outAuth.TokenV2())
+ _, anonac1, _ := s.testClusters["z1111"].ClientsWithToken(outAuth.TokenV2())
outUser2, err := anonac1.CurrentUser()
c.Check(err, check.IsNil)
// z3 anonymous user will be mapped to the z1 anonymous user
@@ -425,14 +321,14 @@ func (s *IntegrationSuite) TestGetCollectionAsAnonymous(c *check.C) {
// Get a token from the login cluster (z1111), use it to submit a
// container request on z2222.
func (s *IntegrationSuite) TestCreateContainerRequestWithFedToken(c *check.C) {
- conn1 := s.conn("z1111")
- rootctx1, _, _ := s.rootClients("z1111")
- _, ac1, _, _ := s.userClients(rootctx1, c, conn1, "z1111", true)
+ conn1 := s.testClusters["z1111"].Conn()
+ rootctx1, _, _ := s.testClusters["z1111"].RootClients()
+ _, ac1, _, _ := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, s.oidcprovider.AuthEmail, true)
// Use ac2 to get the discovery doc with a blank token, so the
// SDK doesn't magically pass the z1111 token to z2222 before
// we're ready to start our test.
- _, ac2, _ := s.clientsWithToken("z2222", "")
+ _, ac2, _ := s.testClusters["z2222"].ClientsWithToken("")
var dd map[string]interface{}
err := ac2.RequestAndDecode(&dd, "GET", "discovery/v1/apis/arvados/v1/rest", nil, nil)
c.Assert(err, check.IsNil)
@@ -495,15 +391,15 @@ func (s *IntegrationSuite) TestCreateContainerRequestWithFedToken(c *check.C) {
// Test for bug #16263
func (s *IntegrationSuite) TestListUsers(c *check.C) {
- rootctx1, _, _ := s.rootClients("z1111")
- conn1 := s.conn("z1111")
- conn3 := s.conn("z3333")
- userctx1, _, _, _ := s.userClients(rootctx1, c, conn1, "z1111", true)
+ rootctx1, _, _ := s.testClusters["z1111"].RootClients()
+ conn1 := s.testClusters["z1111"].Conn()
+ conn3 := s.testClusters["z3333"].Conn()
+ userctx1, _, _, _ := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, s.oidcprovider.AuthEmail, true)
// Make sure LoginCluster is properly configured
for cls := range s.testClusters {
c.Check(
- s.testClusters[cls].config.Clusters[cls].Login.LoginCluster,
+ s.testClusters[cls].Config.Clusters[cls].Login.LoginCluster,
check.Equals, "z1111",
check.Commentf("incorrect LoginCluster config on cluster %q", cls))
}
@@ -564,12 +460,12 @@ func (s *IntegrationSuite) TestListUsers(c *check.C) {
}
func (s *IntegrationSuite) TestSetupUserWithVM(c *check.C) {
- conn1 := s.conn("z1111")
- conn3 := s.conn("z3333")
- rootctx1, rootac1, _ := s.rootClients("z1111")
+ conn1 := s.testClusters["z1111"].Conn()
+ conn3 := s.testClusters["z3333"].Conn()
+ rootctx1, rootac1, _ := s.testClusters["z1111"].RootClients()
// Create user on LoginCluster z1111
- _, _, _, user := s.userClients(rootctx1, c, conn1, "z1111", false)
+ _, _, _, user := s.testClusters["z1111"].UserClients(rootctx1, c, conn1, s.oidcprovider.AuthEmail, true)
// Make a new root token (because rootClients() uses SystemRootToken)
var outAuth arvados.APIClientAuthorization
@@ -577,7 +473,7 @@ func (s *IntegrationSuite) TestSetupUserWithVM(c *check.C) {
c.Check(err, check.IsNil)
// Make a v2 root token to communicate with z3333
- rootctx3, rootac3, _ := s.clientsWithToken("z3333", outAuth.TokenV2())
+ rootctx3, rootac3, _ := s.testClusters["z3333"].ClientsWithToken(outAuth.TokenV2())
// Create VM on z3333
var outVM arvados.VirtualMachine
@@ -628,17 +524,17 @@ func (s *IntegrationSuite) TestSetupUserWithVM(c *check.C) {
}
func (s *IntegrationSuite) TestOIDCAccessTokenAuth(c *check.C) {
- conn1 := s.conn("z1111")
- rootctx1, _, _ := s.rootClients("z1111")
- s.userClients(rootctx1, c, conn1, "z1111", true)
+ conn1 := s.testClusters["z1111"].Conn()
+ rootctx1, _, _ := s.testClusters["z1111"].RootClients()
+ s.testClusters["z1111"].UserClients(rootctx1, c, conn1, s.oidcprovider.AuthEmail, true)
accesstoken := s.oidcprovider.ValidAccessToken()
- for _, clusterid := range []string{"z1111", "z2222"} {
- c.Logf("trying clusterid %s", clusterid)
+ for _, clusterID := range []string{"z1111", "z2222"} {
+ c.Logf("trying clusterid %s", clusterID)
- conn := s.conn(clusterid)
- ctx, ac, kc := s.clientsWithToken(clusterid, accesstoken)
+ conn := s.testClusters[clusterID].Conn()
+ ctx, ac, kc := s.testClusters[clusterID].ClientsWithToken(accesstoken)
var coll arvados.Collection
diff --git a/sdk/go/arvadostest/federation_servers.go b/sdk/go/arvadostest/federation_servers.go
new file mode 100644
index 000000000..da2a9d78c
--- /dev/null
+++ b/sdk/go/arvadostest/federation_servers.go
@@ -0,0 +1,155 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+package arvadostest
+
+import (
+ "bytes"
+ "context"
+ "net/url"
+
+ "git.arvados.org/arvados.git/lib/boot"
+ "git.arvados.org/arvados.git/lib/config"
+ "git.arvados.org/arvados.git/lib/controller/rpc"
+ "git.arvados.org/arvados.git/lib/service"
+ "git.arvados.org/arvados.git/sdk/go/arvados"
+ "git.arvados.org/arvados.git/sdk/go/arvadosclient"
+ "git.arvados.org/arvados.git/sdk/go/auth"
+ "git.arvados.org/arvados.git/sdk/go/ctxlog"
+ "git.arvados.org/arvados.git/sdk/go/keepclient"
+ "gopkg.in/check.v1"
+)
+
+// TestCluster stores a working test cluster data
+type TestCluster struct {
+ Super boot.Supervisor
+ Config arvados.Config
+ ControllerURL *url.URL
+ ClusterID string
+}
+
+type logger struct {
+ loggerfunc func(...interface{})
+}
+
+func (l logger) Log(args ...interface{}) {
+ l.loggerfunc(args)
+}
+
+// NewTestCluster loads the provided configuration, and sets up a test cluster
+// ready for being started.
+func NewTestCluster(srcPath string, clusterID, yamlConf, listenHost string, logWriter func(...interface{})) (*TestCluster, error) {
+ loader := config.NewLoader(bytes.NewBufferString(yamlConf), ctxlog.TestLogger(logger{logWriter}))
+ loader.Path = "-"
+ loader.SkipLegacy = true
+ loader.SkipAPICalls = true
+ cfg, err := loader.Load()
+ if err != nil {
+ return nil, err
+ }
+ return &TestCluster{
+ Super: boot.Supervisor{
+ SourcePath: srcPath,
+ ClusterType: "test",
+ ListenHost: listenHost,
+ ControllerAddr: ":0",
+ OwnTemporaryDatabase: true,
+ Stderr: &service.LogPrefixer{
+ Writer: ctxlog.LogWriter(logWriter),
+ Prefix: []byte("[" + clusterID + "] ")},
+ },
+ Config: *cfg,
+ ClusterID: clusterID,
+ }, nil
+}
+
+// Start the test cluster.
+func (tc *TestCluster) Start() {
+ tc.Super.Start(context.Background(), &tc.Config, "-")
+}
+
+// WaitReady waits for all components to report healthy, and finishes setting
+// up the TestCluster struct.
+func (tc *TestCluster) WaitReady() bool {
+ au, ok := tc.Super.WaitReady()
+ if !ok {
+ return ok
+ }
+ u := url.URL(*au)
+ tc.ControllerURL = &u
+ return ok
+}
+
+// ClientsWithToken returns Context, Arvados.Client and keepclient structs
+// initialized to connect to the cluster with the supplied Arvados token.
+func (tc *TestCluster) ClientsWithToken(token string) (context.Context, *arvados.Client, *keepclient.KeepClient) {
+ cl := tc.Config.Clusters[tc.ClusterID]
+ ctx := auth.NewContext(context.Background(), auth.NewCredentials(token))
+ ac, err := arvados.NewClientFromConfig(&cl)
+ if err != nil {
+ panic(err)
+ }
+ ac.AuthToken = token
+ arv, err := arvadosclient.New(ac)
+ if err != nil {
+ panic(err)
+ }
+ kc := keepclient.New(arv)
+ return ctx, ac, kc
+}
+
+// UserClients logs in as a user called "example", get the user's API token,
+// initialize clients with the API token, set up the user and
+// optionally activate the user. Return client structs for
+// communicating with the cluster on behalf of the 'example' user.
+func (tc *TestCluster) UserClients(rootctx context.Context, c *check.C, conn *rpc.Conn, authEmail string, activate bool) (context.Context, *arvados.Client, *keepclient.KeepClient, arvados.User) {
+ login, err := conn.UserSessionCreate(rootctx, rpc.UserSessionCreateOptions{
+ ReturnTo: ",https://example.com",
+ AuthInfo: rpc.UserSessionAuthInfo{
+ Email: authEmail,
+ FirstName: "Example",
+ LastName: "User",
+ Username: "example",
+ },
+ })
+ c.Assert(err, check.IsNil)
+ redirURL, err := url.Parse(login.RedirectLocation)
+ c.Assert(err, check.IsNil)
+ userToken := redirURL.Query().Get("api_token")
+ c.Logf("user token: %q", userToken)
+ ctx, ac, kc := tc.ClientsWithToken(userToken)
+ user, err := conn.UserGetCurrent(ctx, arvados.GetOptions{})
+ c.Assert(err, check.IsNil)
+ _, err = conn.UserSetup(rootctx, arvados.UserSetupOptions{UUID: user.UUID})
+ c.Assert(err, check.IsNil)
+ if activate {
+ _, err = conn.UserActivate(rootctx, arvados.UserActivateOptions{UUID: user.UUID})
+ c.Assert(err, check.IsNil)
+ user, err = conn.UserGetCurrent(ctx, arvados.GetOptions{})
+ c.Assert(err, check.IsNil)
+ c.Logf("user UUID: %q", user.UUID)
+ if !user.IsActive {
+ c.Fatalf("failed to activate user -- %#v", user)
+ }
+ }
+ return ctx, ac, kc, user
+}
+
+// RootClients returns Context, arvados.Client and keepclient structs initialized
+// to communicate with the cluster as the system root user.
+func (tc *TestCluster) RootClients() (context.Context, *arvados.Client, *keepclient.KeepClient) {
+ return tc.ClientsWithToken(tc.Config.Clusters[tc.ClusterID].SystemRootToken)
+}
+
+// AnonymousClients returns Context, arvados.Client and keepclient structs initialized
+// to communicate with the cluster as the anonymous user.
+func (tc *TestCluster) AnonymousClients() (context.Context, *arvados.Client, *keepclient.KeepClient) {
+ return tc.ClientsWithToken(tc.Config.Clusters[tc.ClusterID].Users.AnonymousUserToken)
+}
+
+// Conn gets rpc connection struct initialized to communicate with the
+// specified cluster.
+func (tc *TestCluster) Conn() *rpc.Conn {
+ return rpc.NewConn(tc.ClusterID, tc.ControllerURL, true, rpc.PassthroughTokenProvider)
+}
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list