Browse Source

Merge pull request #9018 from gyuho/auth-ctx

*: fix server-side lease expire when auth is enabled
Gyuho Lee 8 years ago
parent
commit
b0f0ba7f81
4 changed files with 89 additions and 2 deletions
  1. 3 1
      auth/store.go
  2. 31 0
      auth/store_test.go
  3. 3 1
      etcdserver/server.go
  4. 52 0
      integration/v3_auth_test.go

+ 3 - 1
auth/store.go

@@ -1090,7 +1090,9 @@ func (as *authStore) WithRoot(ctx context.Context) context.Context {
 		"token": token,
 	}
 	tokenMD := metadata.New(mdMap)
-	return metadata.NewOutgoingContext(ctx, tokenMD)
+
+	// use "mdIncomingKey{}" since it's called from local etcdserver
+	return metadata.NewIncomingContext(ctx, tokenMD)
 }
 
 func (as *authStore) HasRole(user, role string) bool {

+ 31 - 0
auth/store_test.go

@@ -701,3 +701,34 @@ func TestRolesOrder(t *testing.T) {
 		}
 	}
 }
+
+// TestAuthInfoFromCtxWithRoot ensures "WithRoot" properly embeds token in the context.
+func TestAuthInfoFromCtxWithRoot(t *testing.T) {
+	b, tPath := backend.NewDefaultTmpBackend()
+	defer os.Remove(tPath)
+
+	tp, err := NewTokenProvider("simple", dummyIndexWaiter)
+	if err != nil {
+		t.Fatal(err)
+	}
+	as := NewAuthStore(b, tp)
+	defer as.Close()
+
+	if err = enableAuthAndCreateRoot(as); err != nil {
+		t.Fatal(err)
+	}
+
+	ctx := context.Background()
+	ctx = as.WithRoot(ctx)
+
+	ai, aerr := as.AuthInfoFromCtx(ctx)
+	if aerr != nil {
+		t.Error(err)
+	}
+	if ai == nil {
+		t.Error("expected non-nil *AuthInfo")
+	}
+	if ai.Username != "root" {
+		t.Errorf("expected user name 'root', got %+v", ai)
+	}
+}

+ 3 - 1
etcdserver/server.go

@@ -770,7 +770,9 @@ func (s *EtcdServer) run() {
 					lid := lease.ID
 					s.goAttach(func() {
 						ctx := s.authStore.WithRoot(s.ctx)
-						s.LeaseRevoke(ctx, &pb.LeaseRevokeRequest{ID: int64(lid)})
+						if _, lerr := s.LeaseRevoke(ctx, &pb.LeaseRevokeRequest{ID: int64(lid)}); lerr != nil {
+							plog.Warningf("failed to revoke %016x (%q)", lid, lerr.Error())
+						}
 						leaseExpired.Inc()
 						<-c
 					})

+ 52 - 0
integration/v3_auth_test.go

@@ -106,6 +106,58 @@ func TestV3AuthRevision(t *testing.T) {
 	}
 }
 
+// TestV3AuthWithLeaseRevokeWithRoot ensures that granted leases
+// with root user be revoked after TTL.
+func TestV3AuthWithLeaseRevokeWithRoot(t *testing.T) {
+	defer testutil.AfterTest(t)
+
+	clus := NewClusterV3(t, &ClusterConfig{Size: 1})
+	defer clus.Terminate(t)
+
+	api := toGRPC(clus.Client(0))
+	authSetupRoot(t, api.Auth)
+
+	rootc, cerr := clientv3.New(clientv3.Config{
+		Endpoints: clus.Client(0).Endpoints(),
+		Username:  "root",
+		Password:  "123",
+	})
+	if cerr != nil {
+		t.Fatal(cerr)
+	}
+	defer rootc.Close()
+
+	leaseResp, err := rootc.Grant(context.TODO(), 2)
+	if err != nil {
+		t.Fatal(err)
+	}
+	leaseID := leaseResp.ID
+
+	if _, err = rootc.Put(context.TODO(), "foo", "bar", clientv3.WithLease(leaseID)); err != nil {
+		t.Fatal(err)
+	}
+
+	// wait for lease expire
+	time.Sleep(3 * time.Second)
+
+	tresp, terr := api.Lease.LeaseTimeToLive(
+		context.TODO(),
+		&pb.LeaseTimeToLiveRequest{
+			ID:   int64(leaseID),
+			Keys: true,
+		},
+	)
+	if terr != nil {
+		t.Error(terr)
+	}
+	if len(tresp.Keys) > 0 || tresp.GrantedTTL != 0 {
+		t.Errorf("lease %016x should have been revoked, got %+v", leaseID, tresp)
+	}
+	if tresp.TTL != -1 {
+		t.Errorf("lease %016x should have been expired, got %+v", leaseID, tresp)
+	}
+}
+
 type user struct {
 	name     string
 	password string