Skip to content

Commit

Permalink
优化用例结构 (onsi#23)
Browse files Browse the repository at this point in the history
* bugfix: loadconfig (onsi#17)

feature: add tenant to request

* WIP:add auth demo

* optimize case structure
  • Loading branch information
LiuqingLiao committed Jan 6, 2021
1 parent 7eec82b commit badcdd4
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 125 deletions.
109 changes: 51 additions & 58 deletions auth/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,20 @@ import (

authclient "github.com/caicloud/auth/pkg/server/client"
"github.com/caicloud/nubela/expect"
"github.com/caicloud/nubela/logger"
"github.com/caicloud/zeus/framework"
"github.com/caicloud/zeus/framework/auth"
"github.com/onsi/ginkgo"
"k8s.io/apimachinery/pkg/util/rand"
)

const (
passwd = "Pwd123456"
)

var operation = []string{"create", "get", "list", "update", "delete"}

//TODO: 所有AfterEach添加删除role,用户操作
var _ = SIGDescribe("命名空间权限管理[permission]", func() {
// TODO: 添加一个判断用户是否为系统用户操作,若为系统用户,则跳过。
// 框架会提供一个租户,该租户已经分配好资源,同时提供该租户的管理员用户。目前框架先写死了。
f := framework.NewDefaultFramework("abc")
var (
authAPI authclient.Interface
nsName string
baseInfo *BaseInfo
baseInfo *auth.BaseInfo
normalUserAuthAPI authclient.Interface
permission, resource []string
err error
Expand All @@ -36,141 +28,142 @@ var _ = SIGDescribe("命名空间权限管理[permission]", func() {
nsQuotaNew := quotaSize("0.25", "0.5Gi", "0.1", "0.2Gi")
ginkgo.Describe("管理权限", func() {
ginkgo.BeforeEach(func() {
permission = []string{"ManageNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
// 创建基础变量并赋值
nsName = rand.String(8)
baseInfo = CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
baseInfo = auth.CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
authAPI, err = f.APIClient.Auth()
if err != nil {
logger.Failf("get auth api failed, %v", err)
}
normalUserAuthAPI = PresetOperation(authAPI, baseInfo, permission, resource)
expect.NoError(err)
})
ginkgo.AfterEach(func() {
//TODO: 添加删除role,用户操作
err = auth.PostsetOperation(authAPI, baseInfo)
expect.NoError(err)
})
ginkgo.It("管理权限", func() {
permission = []string{"ManageNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
normalUserAuthAPI = auth.PresetOperation(authAPI, baseInfo, permission, resource)
errs := crudNamespace(normalUserAuthAPI, baseInfo, nsName, nsQuotaOld, nsQuotaNew)
CheckResult(errs, []bool{true, true, true, true, true}) // 顺序create, get, list, update, delete权限
auth.CheckResult(errs, []bool{true, true, true, true, true}) // 顺序create, get, list, update, delete权限
})
})
ginkgo.Describe("新建权限", func() {
ginkgo.BeforeEach(func() {
permission = []string{"CreateNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
// 创建基础变量并赋值
nsName = rand.String(8)
baseInfo = CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
baseInfo = auth.CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
authAPI, err = f.APIClient.Auth()
if err != nil {
logger.Failf("get auth api failed, %v", err)
}
normalUserAuthAPI = PresetOperation(authAPI, baseInfo, permission, resource)
expect.NoError(err)
})
ginkgo.AfterEach(func() {
err = auth.DeleteNamespace(authAPI, baseInfo.TenantID, baseInfo.ClusterID, nsName)
expect.NoError(err)
err = auth.PostsetOperation(authAPI, baseInfo)
expect.NoError(err)
})
ginkgo.It("新建权限", func() {
permission = []string{"CreateNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
normalUserAuthAPI = auth.PresetOperation(authAPI, baseInfo, permission, resource)
errs := crudNamespace(normalUserAuthAPI, baseInfo, nsName, nsQuotaOld, nsQuotaNew)
CheckResult(errs, []bool{true, true, true, false, false}) // 顺序create, get, list, update, delete权限
auth.CheckResult(errs, []bool{true, true, true, false, false}) // 顺序create, get, list, update, delete权限
})
})
ginkgo.Describe("删除权限", func() {
ginkgo.BeforeEach(func() {
// 创建基础变量并赋值
nsName = rand.String(8)
baseInfo = CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
permission = []string{"DeleteNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID, "trn:cps:::namespace/cluster/" + f.ClusterID + "/" + nsName} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
baseInfo = auth.CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
authAPI, err = f.APIClient.Auth()
if err != nil {
logger.Failf("get auth api failed, %v", err)
}
normalUserAuthAPI = PresetOperation(authAPI, baseInfo, permission, resource)
expect.NoError(err)
_, err = auth.CreateNamespaceAndWait(authAPI, baseInfo.TenantID, nsName, nsQuotaOld, baseInfo.ClusterID)
expect.NoError(err)
})
ginkgo.AfterEach(func() {
err = auth.PostsetOperation(authAPI, baseInfo)
expect.NoError(err)
})
ginkgo.It("删除权限", func() {
permission = []string{"DeleteNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID, "trn:cps:::namespace/cluster/" + f.ClusterID + "/" + nsName} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
normalUserAuthAPI = auth.PresetOperation(authAPI, baseInfo, permission, resource)
errs := crudNamespace(normalUserAuthAPI, baseInfo, nsName, nsQuotaOld, nsQuotaNew)
CheckResult(errs, []bool{false, true, true, false, true}) // 顺序create, get, list, update, delete权限
auth.CheckResult(errs, []bool{false, true, true, false, true}) // 顺序create, get, list, update, delete权限
})
})
ginkgo.Describe("更新权限", func() {
ginkgo.BeforeEach(func() {
// 创建基础变量并赋值
nsName = rand.String(8)
baseInfo = CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
permission = []string{"UpdateNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID, "trn:cps:::namespace/cluster/" + f.ClusterID + "/" + nsName} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
baseInfo = auth.CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
authAPI, err = f.APIClient.Auth()
if err != nil {
logger.Failf("get auth api failed, %v", err)
}
normalUserAuthAPI = PresetOperation(authAPI, baseInfo, permission, resource)
expect.NoError(err)
_, err = auth.CreateNamespaceAndWait(authAPI, baseInfo.TenantID, nsName, nsQuotaOld, baseInfo.ClusterID)
expect.NoError(err)
})
ginkgo.AfterEach(func() {
err = auth.DeleteNamespace(authAPI, baseInfo.TenantID, baseInfo.ClusterID, nsName)
expect.NoError(err)
err = auth.PostsetOperation(authAPI, baseInfo)
expect.NoError(err)
})
ginkgo.It("更新权限", func() {
permission = []string{"UpdateNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID, "trn:cps:::namespace/cluster/" + f.ClusterID + "/" + nsName} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
normalUserAuthAPI = auth.PresetOperation(authAPI, baseInfo, permission, resource)
errs := crudNamespace(normalUserAuthAPI, baseInfo, nsName, nsQuotaOld, nsQuotaNew)
CheckResult(errs, []bool{false, true, true, true, false}) // 顺序create, get, list, update, delete权限
auth.CheckResult(errs, []bool{false, true, true, true, false}) // 顺序create, get, list, update, delete权限
})
})
ginkgo.Describe("查看权限", func() {
ginkgo.BeforeEach(func() {
// 创建基础变量并赋值
nsName = rand.String(8)
baseInfo = CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
permission = []string{"VisitNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID, "trn:cps:::namespace/cluster/" + f.ClusterID + "/" + nsName} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
baseInfo = auth.CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
authAPI, err = f.APIClient.Auth()
if err != nil {
logger.Failf("get auth api failed, %v", err)
}
normalUserAuthAPI = PresetOperation(authAPI, baseInfo, permission, resource)
expect.NoError(err)
_, err = auth.CreateNamespaceAndWait(authAPI, baseInfo.TenantID, nsName, nsQuotaOld, baseInfo.ClusterID)
expect.NoError(err)
})
ginkgo.AfterEach(func() {
err = auth.DeleteNamespace(authAPI, baseInfo.TenantID, baseInfo.ClusterID, nsName)
expect.NoError(err)
err = auth.PostsetOperation(authAPI, baseInfo)
expect.NoError(err)
})
ginkgo.It("查看权限", func() {
permission = []string{"VisitNamespace"}
resource = []string{"trn:cps:::cluster/" + f.ClusterID, "trn:cps:::namespace/cluster/" + f.ClusterID + "/" + nsName} // 格式trn:cps:::resourceType/resourceValue,具体Type,Value和开发沟通,或参考https://bytedance.feishu.cn/docs/doccnUdvIc3bCQ724C87idUQWIe#
normalUserAuthAPI = auth.PresetOperation(authAPI, baseInfo, permission, resource)
errs := crudNamespace(normalUserAuthAPI, baseInfo, nsName, nsQuotaOld, nsQuotaNew)
CheckResult(errs, []bool{false, true, true, false, false}) // 顺序create, get, list, update, delete权限
auth.CheckResult(errs, []bool{false, true, true, false, false}) // 顺序create, get, list, update, delete权限
})
})
ginkgo.Describe("无权限", func() {
ginkgo.BeforeEach(func() {
permission = []string{""}
// 创建基础变量并赋值
nsName = rand.String(8)
baseInfo = CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
baseInfo = auth.CreateBaseInfo(f.PresetResource.Auth.TenantID, f.ClusterID)
authAPI, err = f.APIClient.Auth()
if err != nil {
logger.Failf("get auth api failed, %v", err)
}
normalUserAuthAPI = PresetOperation(authAPI, baseInfo, permission, resource)
expect.NoError(err)
_, err = auth.CreateNamespaceAndWait(authAPI, baseInfo.TenantID, nsName, nsQuotaOld, baseInfo.ClusterID)
expect.NoError(err)
})
ginkgo.AfterEach(func() {
err = auth.DeleteNamespace(authAPI, baseInfo.TenantID, baseInfo.ClusterID, nsName)
expect.NoError(err)
err = auth.PostsetOperation(authAPI, baseInfo)
expect.NoError(err)
})
ginkgo.It("无权限", func() {
permission = []string{""}
normalUserAuthAPI = auth.PresetOperation(authAPI, baseInfo, permission, resource)
errs := crudNamespace(normalUserAuthAPI, baseInfo, nsName, nsQuotaOld, nsQuotaNew)
CheckResult(errs, []bool{false, false, false, false, false}) // 顺序create, get, list, update, delete权限
auth.CheckResult(errs, []bool{false, false, false, false, false}) // 顺序create, get, list, update, delete权限
})
})
})

func crudNamespace(authAPI authclient.Interface, baseInfo *BaseInfo, nsName, quota, newquota string) []error {
func crudNamespace(authAPI authclient.Interface, baseInfo *auth.BaseInfo, nsName, quota, newquota string) []error {
var errs []error
var err error
// 验证create权限
Expand Down
10 changes: 0 additions & 10 deletions framework/auth/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,12 @@ package auth

import (
"context"
"time"

authclient "github.com/caicloud/auth/pkg/server/client"
v20201010 "github.com/caicloud/auth/pkg/server/client/v20201010"
"k8s.io/apimachinery/pkg/util/wait"
)

const (
defaultRequestCPU = "10m"
defaultRequestMem = "10M"
defaultLimitCPU = "100m"
defaultLimitMem = "100M"
interval = time.Second * 2
timeout = time.Second * 10
)

// Describe resource metadate for a namespace
type NamespceMetadate struct {
LimitCPU string
Expand Down
79 changes: 25 additions & 54 deletions auth/util.go → framework/auth/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@ package auth
import (
"context"
"strings"
"time"

authclient "github.com/caicloud/auth/pkg/server/client"
v20201010 "github.com/caicloud/auth/pkg/server/client/v20201010"
"github.com/caicloud/nubela/expect"
"github.com/caicloud/nubela/logger"
"github.com/caicloud/zeus/framework/client"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/rand"
"k8s.io/apimachinery/pkg/util/wait"
)

var operation = []string{"create", "get", "list", "update", "delete"}

const (
interval = time.Second * 2
timeout = time.Second * 10
passwd = "Pwd123456"
)

type BaseInfo struct {
Expand All @@ -28,48 +27,6 @@ type BaseInfo struct {
ClusterID string
}

func CreateTenantAndWait(authAPI authclient.Interface, name, description string) error {
tenantReq := &v20201010.CreateTenantReq{
Name: name,
Description: description,
}
tenant, err := authAPI.V20201010().CreateTenant(context.TODO(), tenantReq)
if err != nil {
return err
}
return wait.PollImmediate(interval, timeout, func() (done bool, err error) {
tenant, err = GetTenant(authAPI, tenant.Name, tenant.UID)
if err != nil {
return false, err
}
if tenant.State == "Active" { // FIXME: this field value need verify.
return true, nil
} else {
logger.Infof("tenant is not ready, retrying...")
return false, nil
}
})
}

func DeleteTenantAndWait(authAPI authclient.Interface, id string) error {
delTenantReq := &v20201010.DeleteTenantReq{UID: id} // XXX: why only support id
_, err := authAPI.V20201010().DeleteTenant(context.TODO(), delTenantReq)
if err != nil {
return err
}
return wait.PollImmediate(interval, timeout, func() (done bool, err error) {
_, err = GetTenant(authAPI, "", id)
if err != nil {
if apierrors.IsNotFound(err) { // FIXME: this error check may not useful
return true, nil
} else {
return false, err
}
}
return false, nil
})
}

func AddTenantMembers(authAPI authclient.Interface, tenantID, userName string, roleNames []string) error {
addTenantMemReq := &v20201010.AddTenantMemberReq{
TenantID: tenantID,
Expand Down Expand Up @@ -122,14 +79,6 @@ func CreateRoleBinding(authAPI authclient.Interface, roleID string, userIDs []st
return err
}

func GetTenant(authAPI authclient.Interface, name, id string) (*v20201010.Tenant, error) {
getTenantReq := &v20201010.GetTenantReq{
Name: name, // Name and ID only need supply one
ID: id,
}
return authAPI.V20201010().GetTenant(context.TODO(), getTenantReq)
}

func GetUser(authAPI authclient.Interface, name string) (*v20201010.UserResp, error) {
getUserReq := &v20201010.GetUserReq{Name: name}
return authAPI.V20201010().GetUser(context.TODO(), getUserReq)
Expand Down Expand Up @@ -186,6 +135,28 @@ func CreateBaseInfo(tenantID, clusterID string) *BaseInfo {
}
}

func DeleteUserAndWait() error {
// TODO: 业务组还未提供删除User的API
return nil
}

func DeleteRole(authAPI authclient.Interface, name string) error {
delRole := &v20201010.DeleteRoleReq{
UID: name,
}
_, err := authAPI.V20201010().DeleteRole(context.TODO(), delRole)
return err
}
func PostsetOperation(authAPI authclient.Interface, baseInfo *BaseInfo) error {
if err := DeleteRole(authAPI, baseInfo.RoleName); err != nil {
return err
}
if err := DeleteUserAndWait(); err != nil {
return err
}
return nil
}

func CheckResult(errs []error, expects []bool) {
for i := 0; i < len(errs); i++ {
if errs[i] == nil {
Expand Down

0 comments on commit badcdd4

Please sign in to comment.