You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2021/12/31 08:25:25 UTC
[servicecomb-service-center] branch master updated: [feat] add role sync func and ut when db is etcd (#1198)
This is an automated email from the ASF dual-hosted git repository.
tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git
The following commit(s) were added to refs/heads/master by this push:
new a983b51 [feat] add role sync func and ut when db is etcd (#1198)
a983b51 is described below
commit a983b51d56a99760ad41087a3e0ad86814485cf8
Author: robotljw <79...@qq.com>
AuthorDate: Fri Dec 31 16:25:18 2021 +0800
[feat] add role sync func and ut when db is etcd (#1198)
---
datasource/common.go | 1 +
datasource/etcd/account_test.go | 16 +++--
datasource/etcd/role.go | 51 ++++++++++++++--
datasource/etcd/role_test.go | 129 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 185 insertions(+), 12 deletions(-)
diff --git a/datasource/common.go b/datasource/common.go
index 90d28cd..f783594 100644
--- a/datasource/common.go
+++ b/datasource/common.go
@@ -33,6 +33,7 @@ const (
Provider = "p"
ResourceAccount = "account"
+ ResourceRole = "role"
)
// WrapErrResponse is temp func here to wait finish to refact the discosvc pkg
diff --git a/datasource/etcd/account_test.go b/datasource/etcd/account_test.go
index 58a36ae..47a3771 100644
--- a/datasource/etcd/account_test.go
+++ b/datasource/etcd/account_test.go
@@ -55,13 +55,15 @@ func TestSyncAccount(t *testing.T) {
_, err = rbac.Instance().DeleteAccount(context.Background(), []string{a1.Name})
assert.NoError(t, err)
listTaskReq := model.ListTaskRequest{
- Domain: "",
- Project: "",
+ Domain: "",
+ Project: "",
+ ResourceType: datasource.ResourceAccount,
}
tasks, err := task.List(context.Background(), &listTaskReq)
assert.NoError(t, err)
assert.Equal(t, 2, len(tasks))
- task.Delete(context.Background(), tasks...)
+ err = task.Delete(context.Background(), tasks...)
+ assert.NoError(t, err)
tombstoneListReq := model.ListTombstoneRequest{
ResourceType: datasource.ResourceAccount,
}
@@ -105,13 +107,15 @@ func TestSyncAccount(t *testing.T) {
_, err = rbac.Instance().DeleteAccount(context.Background(), []string{a2.Name, a3.Name})
assert.NoError(t, err)
listTaskReq := model.ListTaskRequest{
- Domain: "",
- Project: "",
+ Domain: "",
+ Project: "",
+ ResourceType: datasource.ResourceAccount,
}
tasks, err := task.List(context.Background(), &listTaskReq)
assert.NoError(t, err)
assert.Equal(t, 6, len(tasks))
- task.Delete(context.Background(), tasks...)
+ err = task.Delete(context.Background(), tasks...)
+ assert.NoError(t, err)
tombstoneListReq := model.ListTombstoneRequest{
ResourceType: datasource.ResourceAccount,
}
diff --git a/datasource/etcd/role.go b/datasource/etcd/role.go
index f1a1092..9e117d9 100644
--- a/datasource/etcd/role.go
+++ b/datasource/etcd/role.go
@@ -24,13 +24,16 @@ import (
"strconv"
"time"
+ rbacmodel "github.com/go-chassis/cari/rbac"
+ "github.com/go-chassis/cari/sync"
+ "github.com/little-cui/etcdadpt"
+
+ "github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/datasource/etcd/path"
"github.com/apache/servicecomb-service-center/datasource/rbac"
"github.com/apache/servicecomb-service-center/pkg/etcdsync"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/util"
- rbacmodel "github.com/go-chassis/cari/rbac"
- "github.com/little-cui/etcdadpt"
)
func (rm *RbacDAO) CreateRole(ctx context.Context, r *rbacmodel.Role) error {
@@ -61,7 +64,18 @@ func (rm *RbacDAO) CreateRole(ctx context.Context, r *rbacmodel.Role) error {
log.Error("role info is invalid", err)
return err
}
- err = etcdadpt.PutBytes(ctx, key, value)
+ opts := []etcdadpt.OpOptions{
+ etcdadpt.OpPut(etcdadpt.WithStrKey(key), etcdadpt.WithValue(value)),
+ }
+ if datasource.EnableSync {
+ taskOpt, err := GenTaskOpts("", "", sync.CreateAction, datasource.ResourceRole, r)
+ if err != nil {
+ log.Error("", err)
+ return err
+ }
+ opts = append(opts, taskOpt)
+ }
+ err = etcdadpt.Txn(ctx, opts)
if err != nil {
log.Error("can not save account info", err)
return err
@@ -117,11 +131,25 @@ func (rm *RbacDAO) DeleteRole(ctx context.Context, name string) (bool, error) {
if exists {
return false, rbac.ErrRoleBindingExist
}
- del, err := etcdadpt.Delete(ctx, path.GenerateRBACRoleKey(name))
+ opts := []etcdadpt.OpOptions{etcdadpt.OpDel(etcdadpt.WithStrKey(path.GenerateRBACRoleKey(name)))}
+ if datasource.EnableSync {
+ taskOpt, err := GenTaskOpts("", "", sync.DeleteAction, datasource.ResourceRole, name)
+ if err != nil {
+ log.Error("", err)
+ return false, err
+ }
+ tombstoneOpt, err := GenTombstoneOpts("", "", datasource.ResourceRole, name)
+ if err != nil {
+ log.Error("", err)
+ return false, err
+ }
+ opts = append(opts, taskOpt, tombstoneOpt)
+ }
+ err = etcdadpt.Txn(ctx, opts)
if err != nil {
return false, err
}
- return del, nil
+ return true, nil
}
func RoleBindingExists(ctx context.Context, role string) (bool, error) {
_, total, err := etcdadpt.List(ctx, path.GenRoleAccountPrefixIdxKey(role))
@@ -138,5 +166,16 @@ func (rm *RbacDAO) UpdateRole(ctx context.Context, name string, role *rbacmodel.
log.Error("role info is invalid", err)
return err
}
- return etcdadpt.PutBytes(ctx, path.GenerateRBACRoleKey(name), value)
+ opts := []etcdadpt.OpOptions{
+ etcdadpt.OpPut(etcdadpt.WithStrKey(path.GenerateRBACRoleKey(name)), etcdadpt.WithValue(value)),
+ }
+ if datasource.EnableSync {
+ taskOpt, err := GenTaskOpts("", "", sync.UpdateAction, datasource.ResourceRole, role)
+ if err != nil {
+ log.Error("", err)
+ return err
+ }
+ opts = append(opts, taskOpt)
+ }
+ return etcdadpt.Txn(ctx, opts)
}
diff --git a/datasource/etcd/role_test.go b/datasource/etcd/role_test.go
new file mode 100644
index 0000000..0a447c5
--- /dev/null
+++ b/datasource/etcd/role_test.go
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package etcd_test
+
+import (
+ "context"
+ "strconv"
+ "testing"
+
+ rbacmodel "github.com/go-chassis/cari/rbac"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/apache/servicecomb-service-center/datasource"
+ "github.com/apache/servicecomb-service-center/datasource/rbac"
+ "github.com/apache/servicecomb-service-center/eventbase/model"
+ "github.com/apache/servicecomb-service-center/eventbase/service/task"
+ "github.com/apache/servicecomb-service-center/eventbase/service/tombstone"
+ _ "github.com/apache/servicecomb-service-center/test"
+)
+
+func TestSyncRole(t *testing.T) {
+
+ datasource.EnableSync = true
+
+ t.Run("create role", func(t *testing.T) {
+ t.Run("creating a role and delete it will create two tasks and a tombstone should pass", func(t *testing.T) {
+ r1 := rbacmodel.Role{
+ ID: "create-11111",
+ Name: "create-role",
+ Perms: nil,
+ }
+ err := rbac.Instance().CreateRole(context.Background(), &r1)
+ assert.NoError(t, err)
+ r, err := rbac.Instance().GetRole(context.Background(), "create-role")
+ assert.NoError(t, err)
+ assert.Equal(t, r1, *r)
+ dt, _ := strconv.Atoi(r.CreateTime)
+ assert.Less(t, 0, dt)
+ assert.Equal(t, r.CreateTime, r.UpdateTime)
+ _, err = rbac.Instance().DeleteRole(context.Background(), r1.Name)
+ assert.NoError(t, err)
+ listTaskReq := model.ListTaskRequest{
+ Domain: "",
+ Project: "",
+ ResourceType: datasource.ResourceRole,
+ }
+ tasks, err := task.List(context.Background(), &listTaskReq)
+ assert.NoError(t, err)
+ assert.Equal(t, 2, len(tasks))
+ err = task.Delete(context.Background(), tasks...)
+ assert.NoError(t, err)
+ tombstoneListReq := model.ListTombstoneRequest{
+ ResourceType: datasource.ResourceRole,
+ }
+ tombstones, err := tombstone.List(context.Background(), &tombstoneListReq)
+ assert.NoError(t, err)
+ assert.Equal(t, 1, len(tombstones))
+ err = tombstone.Delete(context.Background(), tombstones...)
+ assert.NoError(t, err)
+ })
+ })
+
+ t.Run("update role", func(t *testing.T) {
+ t.Run("create two roles ,then update them, finally delete them, will create six tasks and two tombstones should pass",
+ func(t *testing.T) {
+ r2 := rbacmodel.Role{
+ ID: "update-22222",
+ Name: "update-role-22222",
+ Perms: nil,
+ }
+ r3 := rbacmodel.Role{
+ ID: "update-33333",
+ Name: "update-role-33333",
+ Perms: nil,
+ }
+ err := rbac.Instance().CreateRole(context.Background(), &r2)
+ assert.NoError(t, err)
+ err = rbac.Instance().CreateRole(context.Background(), &r3)
+ assert.NoError(t, err)
+ r2.ID = "update-22222-33333"
+ err = rbac.Instance().UpdateRole(context.Background(), "update-role-22222", &r2)
+ assert.NoError(t, err)
+ r3.ID = "update-33333-44444"
+ err = rbac.Instance().UpdateRole(context.Background(), "update-role-33333", &r3)
+ assert.NoError(t, err)
+ _, err = rbac.Instance().DeleteRole(context.Background(), r2.Name)
+ assert.NoError(t, err)
+ _, err = rbac.Instance().DeleteRole(context.Background(), r3.Name)
+ assert.NoError(t, err)
+ listTaskReq := model.ListTaskRequest{
+ Domain: "",
+ Project: "",
+ ResourceType: datasource.ResourceRole,
+ }
+ tasks, err := task.List(context.Background(), &listTaskReq)
+ assert.NoError(t, err)
+ assert.Equal(t, 6, len(tasks))
+ err = task.Delete(context.Background(), tasks...)
+ assert.NoError(t, err)
+ tombstoneListReq := model.ListTombstoneRequest{
+ ResourceType: datasource.ResourceRole,
+ }
+ tombstones, err := tombstone.List(context.Background(), &tombstoneListReq)
+ assert.NoError(t, err)
+ assert.Equal(t, 2, len(tombstones))
+ err = tombstone.Delete(context.Background(), tombstones...)
+ assert.NoError(t, err)
+
+ })
+ })
+
+ datasource.EnableSync = false
+
+}