未验证 提交 3a79df0d 编写于 作者: K KubeSphere CI Bot 提交者: GitHub

Merge pull request #3467 from RolandMa1986/feat-e2e-restclient

Refine group e2e test
......@@ -74,7 +74,7 @@ require (
github.com/stretchr/testify v1.6.1
github.com/xanzy/ssh-agent v0.2.1 // indirect
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
golang.org/x/net v0.0.0-20200707034311-ab3426394381
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
google.golang.org/grpc v1.30.0
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
......
......@@ -7,6 +7,7 @@ module kubesphere.io/client-go
go 1.13
require (
github.com/go-resty/resty/v2 v2.5.0
k8s.io/apimachinery v0.18.6
k8s.io/client-go v0.18.6
sigs.k8s.io/controller-runtime v0.6.4
......
......@@ -117,6 +117,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-resty/resty/v2 v2.5.0 h1:WFb5bD49/85PO7WgAjZ+/TJQ+Ty1XOcWEfD1zIFCM1c=
github.com/go-resty/resty/v2 v2.5.0/go.mod h1:B88+xCTEwvfD94NOuE6GS1wMlnoKNY8eEiNizfNwOwA=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
......@@ -324,6 +326,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
......@@ -355,6 +359,9 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
......
/*
Copyright 2021 The KubeSphere Authors.
Licensed 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 restclient
import (
rest "k8s.io/client-go/rest"
iamv1alpha2 "kubesphere.io/client-go/restclient/versioned/iam/v1alpha2"
)
// NewForConfig returns a new Client using the provided config and Options.
func NewForConfig(c *rest.Config) (*RestClient, error) {
var rc RestClient
var err error
rc.iamV1alpha2, err = iamv1alpha2.NewForConfig(c)
if err != nil {
return nil, err
}
return &rc, nil
}
// RestClient is a set of restful API clients that doesn't compatible with
// Kube API machinery.
type RestClient struct {
iamV1alpha2 *iamv1alpha2.IamV1alpha2Client
}
// IamV1alpha2 retrieves the IamV1alpha2Client
func (c *RestClient) IamV1alpha2() iamv1alpha2.IamV1alpha2Interface {
return c.iamV1alpha2
}
/*
Copyright 2021 The KubeSphere Authors.
Licensed 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 v1alpha2
import (
"context"
resty "github.com/go-resty/resty/v2"
)
type GroupsGetter interface {
Groups() GroupInterface
}
type GroupInterface interface {
CreateBinding(ctx context.Context, workspace, group, user string) (string, error)
}
type groups struct {
client *resty.Client
}
func newGroups(c *IamV1alpha2Client) *groups {
return &groups{
client: c.client,
}
}
//TODO: to be remoted once we move kubesphere.io/apis out of kubesphere package
type groupMember struct {
UserName string `json:"userName"`
GroupName string `json:"groupName"`
}
// Create takes the representation of a group and creates it. Returns the server's representation of the group, and an error, if there is any.
func (c *groups) CreateBinding(ctx context.Context, workspace, group, user string) (result string, err error) {
members := []groupMember{{
UserName: user,
GroupName: group,
}}
resp, err := c.client.R().
SetHeader("Content-Type", "application/json").
SetBody(members).
SetPathParams(map[string]string{
"workspace": workspace,
}).
Post("/kapis/iam.kubesphere.io/v1alpha2/workspaces/{workspace}/groupbindings")
return resp.String(), err
}
/*
Copyright 2020 The KubeSphere Authors.
Licensed 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 v1alpha2
import (
resty "github.com/go-resty/resty/v2"
rest "k8s.io/client-go/rest"
)
type IamV1alpha2Interface interface {
GroupsGetter
RoleBindingsGetter
}
type IamV1alpha2Client struct {
client *resty.Client
}
func (c *IamV1alpha2Client) Groups() GroupInterface {
return newGroups(c)
}
func (c *IamV1alpha2Client) RoleBindings() RoleBindingInterface {
return newRoleBindings(c)
}
// NewForConfig creates a new IamV1alpha2Client for the given config.
func NewForConfig(c *rest.Config) (*IamV1alpha2Client, error) {
client := resty.New()
client.SetHostURL(c.Host)
if c.BearerToken != "" {
client.SetAuthToken(c.BearerToken)
}
if c.Username != "" {
client.SetBasicAuth(c.Username, c.Password)
}
return &IamV1alpha2Client{client}, nil
}
/*
Copyright 2020 The KubeSphere Authors.
Licensed 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 v1alpha2
import (
"context"
resty "github.com/go-resty/resty/v2"
)
type RoleBindingsGetter interface {
RoleBindings() RoleBindingInterface
}
type RoleBindingInterface interface {
CreateRoleBinding(ctx context.Context, namespace, role, group string) (string, error)
CreateWorkspaceRoleBinding(ctx context.Context, namespace, role, group string) (string, error)
}
type rolebindings struct {
client *resty.Client
}
func newRoleBindings(c *IamV1alpha2Client) *rolebindings {
return &rolebindings{
client: c.client,
}
}
// CreateRoleBinding assembling of a rolebinding object and creates it. Returns the server's response and an error, if there is any.
func (c *rolebindings) CreateRoleBinding(ctx context.Context, namespace, role, group string) (result string, err error) {
roles := []map[string]interface{}{{
"subjects": []map[string]interface{}{
{
"kind": "Group",
"apiGroup": "rbac.authorization.k8s.io",
"name": group,
},
},
"roleRef": map[string]interface{}{
"apiGroup": "rbac.authorization.k8s.io",
"kind": "Role",
"name": role,
},
}}
resp, err := c.client.R().
SetHeader("Content-Type", "application/json").
SetBody(roles).
SetPathParams(map[string]string{
"namespace": namespace,
}).
Post("/kapis/iam.kubesphere.io/v1alpha2/namespaces/{namespace}/rolebindings")
return resp.String(), err
}
// CreateWorkspaceRoleBinding assembling of a workspacerolebinding object and creates it. Returns the server's response, and an error, if there is any.
func (c *rolebindings) CreateWorkspaceRoleBinding(ctx context.Context, workspace, role, group string) (result string, err error) {
roles := []map[string]interface{}{{
"subjects": []map[string]interface{}{
{
"kind": "Group",
"apiGroup": "rbac.authorization.k8s.io",
"name": group,
},
},
"roleRef": map[string]interface{}{
"apiGroup": "iam.kubesphere.io/v1alpha2",
"kind": "WorkspaceRoleBinding",
"name": role,
},
}}
resp, err := c.client.R().
SetHeader("Content-Type", "application/json").
SetBody(roles).
SetPathParams(map[string]string{
"workspace": workspace,
}).
Post("/kapis/iam.kubesphere.io/v1alpha2/workspaces/{workspace}/workspacerolebindings/")
return resp.String(), err
}
......@@ -14,8 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e
package constant
const (
DefaultWorkspaceRoleAdmin = "%v-admin"
DefaultAdminUser = "admin"
DefaultPassword = "P@88w0rd"
LocalAPIServer = "http://127.0.0.1:9090"
)
......@@ -19,6 +19,7 @@ package framework
import (
"context"
"fmt"
"time"
"github.com/onsi/ginkgo" //nolint:stylecheck
"github.com/onsi/gomega"
......@@ -29,11 +30,21 @@ import (
"k8s.io/client-go/rest"
"kubesphere.io/client-go/client"
"kubesphere.io/client-go/client/generic"
"kubesphere.io/client-go/restclient"
"kubesphere.io/kubesphere/pkg/apis"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/test/e2e/framework/workspace"
)
const (
// Using the same interval as integration should be fine given the
// minimal load that the apiserver is likely to be under.
PollInterval = 50 * time.Millisecond
// How long to try single API calls (like 'get' or 'list'). Used to prevent
// transient failures from failing tests.
DefaultSingleCallTimeout = 30 * time.Second
)
type Framework struct {
BaseName string
Workspace string
......@@ -45,6 +56,7 @@ type Framework struct {
// that the implementation can vary without affecting tests.
type KubeSphereFramework interface {
GenericClient(userAgent string) client.Client
RestClient(userAgent string) *restclient.RestClient
KubeSphereSystemNamespace() string
// Name of the workspace for the current test to target
......@@ -54,6 +66,8 @@ type KubeSphereFramework interface {
CreateNamespace(name string) string
// Get Names of the namespaces for the current test to target
GetNamespaceNames() []string
GetScheme() *runtime.Scheme
}
func NewKubeSphereFramework(baseName string) KubeSphereFramework {
......@@ -65,6 +79,7 @@ func NewKubeSphereFramework(baseName string) KubeSphereFramework {
if err := scheme.AddToScheme(sch); err != nil {
Failf("unable add Kubernetes APIs to scheme: %v", err)
}
f := &Framework{
BaseName: baseName,
Scheme: sch,
......@@ -97,7 +112,7 @@ func CreateTestWorkSpace(client client.Client, baseName string) string {
wspt.GenerateName = fmt.Sprintf("e2e-tests-%v-", baseName)
wspt, err := workspace.CreateWorkspace(client, wspt)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
ginkgo.By(fmt.Sprintf("Created test namespace %s", wspt.Name))
ginkgo.By(fmt.Sprintf("Created test workspace %s", wspt.Name))
return wspt.Name
}
......@@ -106,6 +121,7 @@ func (f *Framework) GetNamespaceNames() []string {
}
func (f *Framework) CreateNamespace(name string) string {
name = fmt.Sprintf("%s-%s", f.Workspace, name)
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
......@@ -133,19 +149,32 @@ func (f *Framework) KubeSphereSystemNamespace() string {
func (f *Framework) GenericClient(userAgent string) client.Client {
ctx := TestContext
config := &rest.Config{
Host: "127.0.0.1:9090",
Username: "admin",
Password: "P@88w0rd",
}
if ctx.Host != "" {
config = &rest.Config{
Host: ctx.Host,
Username: ctx.Username,
Password: ctx.Password,
}
Host: ctx.Host,
Username: ctx.Username,
Password: ctx.Password,
}
rest.AddUserAgent(config, userAgent)
return generic.NewForConfigOrDie(config, client.Options{Scheme: f.Scheme})
}
func (f *Framework) RestClient(userAgent string) *restclient.RestClient {
ctx := TestContext
config := &rest.Config{
Host: ctx.Host,
Username: ctx.Username,
Password: ctx.Password,
}
c, err := restclient.NewForConfig(config)
if err != nil {
panic(err)
}
return c
}
func (f *Framework) GetScheme() *runtime.Scheme {
return f.Scheme
}
......@@ -41,7 +41,7 @@ func NewUser(name, globelRole string) *iamv1alpha2.User {
},
},
Spec: iamv1alpha2.UserSpec{
Email: fmt.Sprint("%v@kubesphere.io", name),
Email: fmt.Sprintf("%s@kubesphere.io", name),
EncryptedPassword: "P@88w0rd",
},
}
......
/*
Copyright 2021 KubeSphere Authors
Licensed 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 iam
import (
"context"
"fmt"
"golang.org/x/oauth2"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
"kubesphere.io/client-go/client"
"kubesphere.io/client-go/client/generic"
"kubesphere.io/client-go/restclient"
"kubesphere.io/kubesphere/test/e2e/framework"
)
//NewClient creates a new client with user authencation
func NewClient(s *runtime.Scheme, user, passsword string) (client.Client, error) {
ctx := framework.TestContext
token, err := getToken(ctx.Host, user, passsword)
if err != nil {
return nil, err
}
config := &rest.Config{
Host: ctx.Host,
BearerToken: token.AccessToken,
}
return generic.New(config, client.Options{Scheme: s})
}
func NewRestClient(user, passsword string) (*restclient.RestClient, error) {
ctx := framework.TestContext
token, err := getToken(ctx.Host, user, passsword)
if err != nil {
return nil, err
}
config := &rest.Config{
Host: ctx.Host,
BearerToken: token.AccessToken,
}
return restclient.NewForConfig(config)
}
func getToken(host, user, password string) (*oauth2.Token, error) {
config := &oauth2.Config{
Endpoint: oauth2.Endpoint{
TokenURL: fmt.Sprintf("%s/oauth/token", host),
AuthStyle: oauth2.AuthStyleInParams,
},
}
return config.PasswordCredentialsToken(context.TODO(), user, password)
}
/*
Copyright 2021 KubeSphere Authors
Licensed 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 resource
import (
"context"
v1 "k8s.io/api/core/v1"
"kubesphere.io/client-go/client"
)
// ListPods gets the Pods by namespace. If the returned error is nil, the returned PodList is valid.
func ListPods(c client.Client, namespace string) (*v1.PodList, error) {
pods := &v1.PodList{}
err := c.List(context.TODO(), pods, &client.ListOptions{Namespace: namespace})
if err != nil {
return nil, err
}
return pods, nil
}
......@@ -19,6 +19,8 @@ package framework
import (
"flag"
"os"
"kubesphere.io/kubesphere/test/e2e/constant"
)
type TestContextType struct {
......@@ -41,7 +43,22 @@ func registerFlags(t *TestContextType) {
var TestContext *TestContextType = &TestContextType{}
func setDefaultValue(t *TestContextType) {
if t.Host == "" {
t.Host = constant.LocalAPIServer
}
if t.Username == "" {
t.Username = constant.DefaultAdminUser
}
if t.Password == "" {
t.Password = constant.DefaultPassword
}
}
func ParseFlags() {
registerFlags(TestContext)
flag.Parse()
setDefaultValue(TestContext)
}
......@@ -17,34 +17,115 @@ limitations under the License.
package e2e
import (
"context"
"fmt"
. "github.com/onsi/ginkgo" //nolint:stylecheck
. "github.com/onsi/gomega" //nolint:stylecheck
"k8s.io/apimachinery/pkg/util/wait"
"kubesphere.io/client-go/client"
"kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
"kubesphere.io/kubesphere/test/e2e/constant"
"kubesphere.io/kubesphere/test/e2e/framework"
"kubesphere.io/kubesphere/test/e2e/framework/iam"
"kubesphere.io/kubesphere/test/e2e/framework/resource"
apierrors "k8s.io/apimachinery/pkg/api/errors"
)
var _ = Describe("Worksspace", func() {
const (
GroupName = "test-group"
UserName = "tester"
)
var _ = Describe("Groups", func() {
f := framework.NewKubeSphereFramework("group")
var wsName = ""
var gclient client.Client
var workspace = ""
var namespace = ""
var group = ""
var userClient client.Client
adminClient := f.GenericClient("group")
restClient := f.RestClient("group")
Context("Grant Permissions by assign user to group", func() {
It("Should create group and assign members successfully", func() {
By("Expecting to create test workspace for Group tests")
workspace = f.TestWorkSpaceName()
namespace = f.CreateNamespace("group")
g, err := iam.CreateGroup(adminClient, iam.NewGroup(GroupName, workspace), workspace)
framework.ExpectNoError(err)
group = g.Name
Eventually(func() bool {
expGroup, err := iam.GetGroup(adminClient, group, workspace)
return err == nil && expGroup.Name == group
}, timeout, interval).Should(BeTrue())
By("Create user and wait until active")
u, err := createUserWithWait(f, adminClient, UserName)
framework.ExpectNoError(err)
By("Assign user to Group")
_, err = restClient.IamV1alpha2().Groups().CreateBinding(context.TODO(), workspace, group, UserName)
framework.ExpectNoError(err)
By("Creating a new client with user authentication")
userClient, err = iam.NewClient(f.GetScheme(), u.Name, constant.DefaultPassword)
framework.ExpectNoError(err)
})
It(fmt.Sprintf("%s has no permissions to access namespace: %s", UserName, namespace), func() {
err := CheckNamespaceAccess(f, userClient, namespace)
Expect(apierrors.IsForbidden(err)).To(BeTrue())
})
It(fmt.Sprintf("%s should has full access namespace: %s", UserName, namespace), func() {
rolename := fmt.Sprintf("%s-regular", workspace)
By("Grant namespace permission by bind admin role to group")
_, err := restClient.IamV1alpha2().RoleBindings().CreateRoleBinding(context.TODO(), namespace, "admin", group)
framework.ExpectNoError(err)
_, err = restClient.IamV1alpha2().RoleBindings().CreateWorkspaceRoleBinding(context.TODO(), workspace, rolename, group)
framework.ExpectNoError(err)
err = CheckNamespaceAccess(f, userClient, namespace)
framework.ExpectNoError(err)
})
BeforeEach(func() {
gclient = f.GenericClient("group")
})
})
It("Should create group successfully", func() {
// Todo: The can-i API should be a better option, but ks-apiserver doesn't support it yet.
// So we will try to list objects in the namespace.
func CheckNamespaceAccess(f framework.KubeSphereFramework, c client.Client, namespace string) error {
_, err := resource.ListPods(c, namespace)
return err
}
By("Expecting to create workspace thronght workspace template")
wsName = f.TestWorkSpaceName()
// Create a user and wait until the user became active status.
func createUserWithWait(f framework.KubeSphereFramework, c client.Client, username string) (*v1alpha2.User, error) {
u := iam.NewUser(username, "platform-regular")
if _, err := iam.CreateUser(c, u); err != nil {
return nil, err
}
group, err := iam.CreateGroup(gclient, iam.NewGroup("group1", wsName), wsName)
framework.ExpectNoError(err)
Eventually(func() bool {
expGroup, err := iam.GetGroup(gclient, group.Name, wsName)
return err == nil && expGroup.Name == group.Name
}, timeout, interval).Should(BeTrue())
err := wait.PollImmediate(framework.PollInterval, framework.DefaultSingleCallTimeout, func() (bool, error) {
u, err := iam.GetUser(c, username)
if err != nil {
framework.Failf("Cannot retrieve User %q: %v", username, err)
return false, err
}
if u == nil || u.Status.State == nil {
return false, nil
}
return *u.Status.State == v1alpha2.UserActive, nil
})
})
if err != nil {
return nil, err
}
return u, nil
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册