You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by GitBox <gi...@apache.org> on 2021/05/31 06:31:46 UTC

[GitHub] [servicecomb-service-center] humingcheng opened a new pull request #1029: Add account/auth error code

humingcheng opened a new pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029


   Follow this checklist to help us incorporate your contribution quickly and easily:
   
    - [ ] Make sure there is a [JIRA issue](https://issues.apache.org/jira/browse/SCB) filed for the change (usually before you start working on it).  Trivial changes like typos do not require a JIRA issue.  Your pull request should address just this issue, without pulling in other changes.
    - [ ] Each commit in the pull request should have a meaningful subject line and body.
    - [ ] Format the pull request title like `[SCB-XXX] Fixes bug in ApproximateQuantiles`, where you replace `SCB-XXX` with the appropriate JIRA issue.
    - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
    - [ ] Run `go build` `go test` `go fmt` `go vet` to make sure basic checks pass. A more thorough check will be performed on your pull request automatically.
    - [ ] If this contribution is large, please file an Apache [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf).
    - [ ] Never comment source code, delete it.
    - [ ] UT should has "context, subject, expected result" result as test case name, when you call t.Run().
   ---
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] little-cui commented on a change in pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
little-cui commented on a change in pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029#discussion_r642276814



##########
File path: server/resource/v4/auth_resource.go
##########
@@ -145,29 +124,16 @@ func (ar *AuthResource) ListAccount(w http.ResponseWriter, r *http.Request) {
 }
 
 func (ar *AuthResource) GetAccount(w http.ResponseWriter, r *http.Request) {
-	a, err := dao.GetAccount(r.Context(), r.URL.Query().Get(":name"))
+	a, err := rbacsvc.GetAccount(r.Context(), r.URL.Query().Get(":name"))
 	if err != nil {
 		log.Error(errorsEx.MsgGetAccountFailed, err)
-		rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetAccountFailed)
+		writeErrsvcOrInternalErr(w, err)
 		return
 	}
 	a.Password = ""
 	rest.WriteResponse(w, r, nil, a)
 }
 
-func (ar *AuthResource) illegalCheck(w http.ResponseWriter, req *http.Request, name string) bool {
-	if name == rbacsvc.RootName {
-		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateRoot)
-		return true
-	}
-	user := rbacsvc.UserFromContext(req.Context())
-	if name == user {
-		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateYour)
-		return true
-	}
-	return false

Review comment:
       这些校验都改丢了?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] little-cui commented on a change in pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
little-cui commented on a change in pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029#discussion_r642301223



##########
File path: server/service/rbac/account_service.go
##########
@@ -0,0 +1,179 @@
+/*
+ * 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 rbac is dao layer API to help service center manage account, policy and role info
+package rbac
+
+import (
+	"context"
+	"fmt"
+	"github.com/apache/servicecomb-service-center/datasource"
+	errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
+	"github.com/apache/servicecomb-service-center/pkg/log"
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	"github.com/apache/servicecomb-service-center/server/service/validator"
+	"github.com/go-chassis/cari/discovery"
+	"github.com/go-chassis/cari/rbac"
+)
+
+//CreateAccount save 2 kv
+//1. account info
+func CreateAccount(ctx context.Context, a *rbac.Account) error {
+	quotaCheckErr := quota.Apply(ctx, quota.NewApplyQuotaResource(quota.TypeAccount,
+		util.ParseDomainProject(ctx), "", 1))
+	if quotaCheckErr != nil {
+		return quotaCheckErr
+	}
+	err := validator.ValidateCreateAccount(a)
+	if err != nil {
+		log.Errorf(err, "create account [%s] failed", a.Name)
+		return rbac.NewError(discovery.ErrInvalidParams, err.Error())
+	}
+	err = a.Check()
+	if err != nil {
+		log.Errorf(err, "create account [%s] failed", a.Name)
+		return rbac.NewError(discovery.ErrInvalidParams, err.Error())
+	}
+	if err = checkRoleNames(a.Roles); err != nil {
+		return rbac.NewError(rbac.ErrAccountHasInvalidRole, err.Error())
+	}
+
+	err = datasource.Instance().CreateAccount(ctx, a)
+	if err == nil {
+		log.Infof("create account [%s] success", a.Name)
+		return nil
+	}
+	log.Errorf(err, "create account [%s] failed", a.Name)
+	if err == datasource.ErrAccountDuplicated {
+		return rbac.NewError(rbac.ErrAccountConflict, err.Error())
+	}
+	return err
+}
+
+// UpdateAccount updates an account's info, except the password
+func UpdateAccount(ctx context.Context, name string, a *rbac.Account) error {
+	// todo params validation
+	if err := illegalCheck(ctx, name); err != nil {
+		return err
+	}
+	if len(a.Status) == 0 && len(a.Roles) == 0 {
+		return rbac.NewError(discovery.ErrInvalidParams, "status and roles cannot be empty both")
+	}
+
+	oldAccount, err := GetAccount(ctx, name)
+	if err != nil {
+		log.Errorf(err, "get account [%s] failed", name)
+		return err
+	}
+	if len(a.Status) != 0 {
+		oldAccount.Status = a.Status
+	}
+	if len(a.Roles) != 0 {
+		oldAccount.Roles = a.Roles
+	}
+	if err = checkRoleNames(oldAccount.Roles); err != nil {
+		return rbac.NewError(rbac.ErrAccountHasInvalidRole, err.Error())
+	}
+	err = datasource.Instance().UpdateAccount(ctx, name, oldAccount)
+	if err != nil {
+		log.Errorf(err, "can not edit account info")
+		return err
+	}
+	log.Infof("account [%s] is edit", oldAccount.ID)
+	return nil
+}
+
+func GetAccount(ctx context.Context, name string) (*rbac.Account, error) {
+	r, err := datasource.Instance().GetAccount(ctx, name)
+	if err != nil {
+		if err == datasource.ErrAccountNotExist {
+			msg := fmt.Sprintf("account [%s] not exist", name)
+			return nil, rbac.NewError(rbac.ErrAccountNotExist, msg)
+		}
+		return nil, err
+	}
+	return r, nil
+}
+func ListAccount(ctx context.Context) ([]*rbac.Account, int64, error) {
+	return datasource.Instance().ListAccount(ctx)
+}
+func AccountExist(ctx context.Context, name string) (bool, error) {
+	return datasource.Instance().AccountExist(ctx, name)
+}
+func DeleteAccount(ctx context.Context, name string) error {
+	if err := illegalCheck(ctx, name); err != nil {
+		return err
+	}
+	exist, err := datasource.Instance().AccountExist(ctx, name)
+	if err != nil {
+		log.Errorf(err, "check account [%s] exit failed", name)
+		return err
+	}
+	if !exist {
+		msg := fmt.Sprintf("account [%s] not exist", name)
+		return rbac.NewError(rbac.ErrAccountNotExist, msg)
+	}
+	_, err = datasource.Instance().DeleteAccount(ctx, []string{name})
+	return err
+}
+
+//CreateAccount save 2 kv
+//1. account info
+func EditAccount(ctx context.Context, a *rbac.Account) error {
+	exist, err := datasource.Instance().AccountExist(ctx, a.Name)
+	if err != nil {
+		log.Errorf(err, "can not edit account info")
+		return err
+	}
+	if !exist {
+		return rbac.NewError(rbac.ErrAccountNotExist, "")
+	}
+
+	err = datasource.Instance().UpdateAccount(ctx, a.Name, a)
+	if err != nil {
+		log.Errorf(err, "can not edit account info")
+		return err
+	}
+	log.Infof("account [%s] is edit", a.ID)
+	return nil
+}
+
+func checkRoleNames(roles []string) error {
+	for _, name := range roles {
+		exist, err := RoleExist(context.TODO(), name)

Review comment:
       不允许业务代码中出现context.TODO,request上下文场景应该用一直传递context




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] little-cui merged pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
little-cui merged pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] humingcheng commented on a change in pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
humingcheng commented on a change in pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029#discussion_r642282584



##########
File path: server/resource/v4/auth_resource.go
##########
@@ -145,29 +124,16 @@ func (ar *AuthResource) ListAccount(w http.ResponseWriter, r *http.Request) {
 }
 
 func (ar *AuthResource) GetAccount(w http.ResponseWriter, r *http.Request) {
-	a, err := dao.GetAccount(r.Context(), r.URL.Query().Get(":name"))
+	a, err := rbacsvc.GetAccount(r.Context(), r.URL.Query().Get(":name"))
 	if err != nil {
 		log.Error(errorsEx.MsgGetAccountFailed, err)
-		rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetAccountFailed)
+		writeErrsvcOrInternalErr(w, err)
 		return
 	}
 	a.Password = ""
 	rest.WriteResponse(w, r, nil, a)
 }
 
-func (ar *AuthResource) illegalCheck(w http.ResponseWriter, req *http.Request, name string) bool {
-	if name == rbacsvc.RootName {
-		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateRoot)
-		return true
-	}
-	user := rbacsvc.UserFromContext(req.Context())
-	if name == user {
-		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateYour)
-		return true
-	}
-	return false

Review comment:
       移到了这里,删除,更新都保留检查:
   https://github.com/apache/servicecomb-service-center/pull/1029/files#diff-b12045f836975d685f7b9152bef486b33d9dbc2277f228072ab7a226cb4329c7R69-R74




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] humingcheng commented on a change in pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
humingcheng commented on a change in pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029#discussion_r642407055



##########
File path: server/service/rbac/rbac.go
##########
@@ -123,7 +122,7 @@ func initFirstTime(admin string) {
 		log.Fatal("invalid pwd", err)
 		return
 	}
-	if err := dao.CreateAccount(context.Background(), a); err != nil {
+	if err := datasource.Instance().CreateAccount(context.Background(), a); err != nil {

Review comment:
       done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] humingcheng commented on a change in pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
humingcheng commented on a change in pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029#discussion_r642282584



##########
File path: server/resource/v4/auth_resource.go
##########
@@ -145,29 +124,16 @@ func (ar *AuthResource) ListAccount(w http.ResponseWriter, r *http.Request) {
 }
 
 func (ar *AuthResource) GetAccount(w http.ResponseWriter, r *http.Request) {
-	a, err := dao.GetAccount(r.Context(), r.URL.Query().Get(":name"))
+	a, err := rbacsvc.GetAccount(r.Context(), r.URL.Query().Get(":name"))
 	if err != nil {
 		log.Error(errorsEx.MsgGetAccountFailed, err)
-		rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetAccountFailed)
+		writeErrsvcOrInternalErr(w, err)
 		return
 	}
 	a.Password = ""
 	rest.WriteResponse(w, r, nil, a)
 }
 
-func (ar *AuthResource) illegalCheck(w http.ResponseWriter, req *http.Request, name string) bool {
-	if name == rbacsvc.RootName {
-		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateRoot)
-		return true
-	}
-	user := rbacsvc.UserFromContext(req.Context())
-	if name == user {
-		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateYour)
-		return true
-	}
-	return false

Review comment:
       https://github.com/apache/servicecomb-service-center/pull/1029/files#diff-b12045f836975d685f7b9152bef486b33d9dbc2277f228072ab7a226cb4329c7R69-R74




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] humingcheng commented on a change in pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
humingcheng commented on a change in pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029#discussion_r642282584



##########
File path: server/resource/v4/auth_resource.go
##########
@@ -145,29 +124,16 @@ func (ar *AuthResource) ListAccount(w http.ResponseWriter, r *http.Request) {
 }
 
 func (ar *AuthResource) GetAccount(w http.ResponseWriter, r *http.Request) {
-	a, err := dao.GetAccount(r.Context(), r.URL.Query().Get(":name"))
+	a, err := rbacsvc.GetAccount(r.Context(), r.URL.Query().Get(":name"))
 	if err != nil {
 		log.Error(errorsEx.MsgGetAccountFailed, err)
-		rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetAccountFailed)
+		writeErrsvcOrInternalErr(w, err)
 		return
 	}
 	a.Password = ""
 	rest.WriteResponse(w, r, nil, a)
 }
 
-func (ar *AuthResource) illegalCheck(w http.ResponseWriter, req *http.Request, name string) bool {
-	if name == rbacsvc.RootName {
-		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateRoot)
-		return true
-	}
-	user := rbacsvc.UserFromContext(req.Context())
-	if name == user {
-		rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateYour)
-		return true
-	}
-	return false

Review comment:
       移到了这里:
   https://github.com/apache/servicecomb-service-center/pull/1029/files#diff-b12045f836975d685f7b9152bef486b33d9dbc2277f228072ab7a226cb4329c7R69-R74




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] tianxiaoliang commented on a change in pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
tianxiaoliang commented on a change in pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029#discussion_r642297244



##########
File path: server/service/rbac/rbac.go
##########
@@ -123,7 +122,7 @@ func initFirstTime(admin string) {
 		log.Fatal("invalid pwd", err)
 		return
 	}
-	if err := dao.CreateAccount(context.Background(), a); err != nil {
+	if err := datasource.Instance().CreateAccount(context.Background(), a); err != nil {

Review comment:
       rbacsvc.createxxx
   
   cleancode要求不要暴露内部结构




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [servicecomb-service-center] humingcheng commented on a change in pull request #1029: Add account/auth error code

Posted by GitBox <gi...@apache.org>.
humingcheng commented on a change in pull request #1029:
URL: https://github.com/apache/servicecomb-service-center/pull/1029#discussion_r642406916



##########
File path: server/service/rbac/account_service.go
##########
@@ -0,0 +1,179 @@
+/*
+ * 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 rbac is dao layer API to help service center manage account, policy and role info
+package rbac
+
+import (
+	"context"
+	"fmt"
+	"github.com/apache/servicecomb-service-center/datasource"
+	errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
+	"github.com/apache/servicecomb-service-center/pkg/log"
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	"github.com/apache/servicecomb-service-center/server/service/validator"
+	"github.com/go-chassis/cari/discovery"
+	"github.com/go-chassis/cari/rbac"
+)
+
+//CreateAccount save 2 kv
+//1. account info
+func CreateAccount(ctx context.Context, a *rbac.Account) error {
+	quotaCheckErr := quota.Apply(ctx, quota.NewApplyQuotaResource(quota.TypeAccount,
+		util.ParseDomainProject(ctx), "", 1))
+	if quotaCheckErr != nil {
+		return quotaCheckErr
+	}
+	err := validator.ValidateCreateAccount(a)
+	if err != nil {
+		log.Errorf(err, "create account [%s] failed", a.Name)
+		return rbac.NewError(discovery.ErrInvalidParams, err.Error())
+	}
+	err = a.Check()
+	if err != nil {
+		log.Errorf(err, "create account [%s] failed", a.Name)
+		return rbac.NewError(discovery.ErrInvalidParams, err.Error())
+	}
+	if err = checkRoleNames(a.Roles); err != nil {
+		return rbac.NewError(rbac.ErrAccountHasInvalidRole, err.Error())
+	}
+
+	err = datasource.Instance().CreateAccount(ctx, a)
+	if err == nil {
+		log.Infof("create account [%s] success", a.Name)
+		return nil
+	}
+	log.Errorf(err, "create account [%s] failed", a.Name)
+	if err == datasource.ErrAccountDuplicated {
+		return rbac.NewError(rbac.ErrAccountConflict, err.Error())
+	}
+	return err
+}
+
+// UpdateAccount updates an account's info, except the password
+func UpdateAccount(ctx context.Context, name string, a *rbac.Account) error {
+	// todo params validation
+	if err := illegalCheck(ctx, name); err != nil {
+		return err
+	}
+	if len(a.Status) == 0 && len(a.Roles) == 0 {
+		return rbac.NewError(discovery.ErrInvalidParams, "status and roles cannot be empty both")
+	}
+
+	oldAccount, err := GetAccount(ctx, name)
+	if err != nil {
+		log.Errorf(err, "get account [%s] failed", name)
+		return err
+	}
+	if len(a.Status) != 0 {
+		oldAccount.Status = a.Status
+	}
+	if len(a.Roles) != 0 {
+		oldAccount.Roles = a.Roles
+	}
+	if err = checkRoleNames(oldAccount.Roles); err != nil {
+		return rbac.NewError(rbac.ErrAccountHasInvalidRole, err.Error())
+	}
+	err = datasource.Instance().UpdateAccount(ctx, name, oldAccount)
+	if err != nil {
+		log.Errorf(err, "can not edit account info")
+		return err
+	}
+	log.Infof("account [%s] is edit", oldAccount.ID)
+	return nil
+}
+
+func GetAccount(ctx context.Context, name string) (*rbac.Account, error) {
+	r, err := datasource.Instance().GetAccount(ctx, name)
+	if err != nil {
+		if err == datasource.ErrAccountNotExist {
+			msg := fmt.Sprintf("account [%s] not exist", name)
+			return nil, rbac.NewError(rbac.ErrAccountNotExist, msg)
+		}
+		return nil, err
+	}
+	return r, nil
+}
+func ListAccount(ctx context.Context) ([]*rbac.Account, int64, error) {
+	return datasource.Instance().ListAccount(ctx)
+}
+func AccountExist(ctx context.Context, name string) (bool, error) {
+	return datasource.Instance().AccountExist(ctx, name)
+}
+func DeleteAccount(ctx context.Context, name string) error {
+	if err := illegalCheck(ctx, name); err != nil {
+		return err
+	}
+	exist, err := datasource.Instance().AccountExist(ctx, name)
+	if err != nil {
+		log.Errorf(err, "check account [%s] exit failed", name)
+		return err
+	}
+	if !exist {
+		msg := fmt.Sprintf("account [%s] not exist", name)
+		return rbac.NewError(rbac.ErrAccountNotExist, msg)
+	}
+	_, err = datasource.Instance().DeleteAccount(ctx, []string{name})
+	return err
+}
+
+//CreateAccount save 2 kv
+//1. account info
+func EditAccount(ctx context.Context, a *rbac.Account) error {
+	exist, err := datasource.Instance().AccountExist(ctx, a.Name)
+	if err != nil {
+		log.Errorf(err, "can not edit account info")
+		return err
+	}
+	if !exist {
+		return rbac.NewError(rbac.ErrAccountNotExist, "")
+	}
+
+	err = datasource.Instance().UpdateAccount(ctx, a.Name, a)
+	if err != nil {
+		log.Errorf(err, "can not edit account info")
+		return err
+	}
+	log.Infof("account [%s] is edit", a.ID)
+	return nil
+}
+
+func checkRoleNames(roles []string) error {
+	for _, name := range roles {
+		exist, err := RoleExist(context.TODO(), name)

Review comment:
       done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org