feat: kubesphere 4.0 (#6115)

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

---------

Signed-off-by: ci-bot <ci-bot@kubesphere.io>
Co-authored-by: ks-ci-bot <ks-ci-bot@example.com>
Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
KubeSphere CI Bot
2024-09-06 11:05:52 +08:00
committed by GitHub
parent b5015ec7b9
commit 447a51f08b
8557 changed files with 546695 additions and 1146174 deletions

View File

@@ -1,24 +1,7 @@
/*
Copyright 2020 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 constant
const (
DefaultWorkspaceRoleAdmin = "%v-admin"
DefaultAdminUser = "admin"
DefaultPassword = "P@88w0rd"
LocalAPIServer = "http://127.0.0.1:9090"
DefaultAdminUser = "admin"
DefaultPassword = "P@88w0rd"
LocalAPIServer = "http://127.0.0.1:9090"
)

View File

@@ -1,26 +1,10 @@
/*
Copyright 2020 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 e2e
import (
"testing"
"github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
"k8s.io/klog/v2"

View File

@@ -1,19 +1,3 @@
/*
Copyright 2020 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 e2e
import (

View File

@@ -1,19 +1,3 @@
/*
Copyright 2020 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 framework
import (

View File

@@ -1,184 +1,51 @@
/*
Copyright 2020 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 framework
import (
"context"
"fmt"
"time"
"github.com/onsi/ginkgo" //nolint:stylecheck
"github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/onsi/ginkgo/v2"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/scheme"
"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
"kubesphere.io/client-go/kubesphere/scheme"
"kubesphere.io/client-go/rest"
)
type Framework struct {
BaseName string
Workspace string
Namespaces []string
Scheme *runtime.Scheme
}
// KubeSphereFramework provides an interface to a test control plane so
// 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
TestWorkSpaceName() string
// Create a Namespace under current Worksapce
CreateNamespace(name string) string
// Get Names of the namespaces for the current test to target
GetNamespaceNames() []string
GetScheme() *runtime.Scheme
RestClient() *rest.RESTClient
}
func NewKubeSphereFramework(baseName string) KubeSphereFramework {
sch := runtime.NewScheme()
if err := apis.AddToScheme(sch); err != nil {
Failf("unable add KubeSphere APIs to scheme: %v", err)
}
if err := scheme.AddToScheme(sch); err != nil {
Failf("unable add Kubernetes APIs to scheme: %v", err)
}
f := &Framework{
BaseName: baseName,
Scheme: sch,
}
func NewKubeSphereFramework() KubeSphereFramework {
f := &Framework{}
ginkgo.AfterEach(f.AfterEach)
ginkgo.BeforeEach(f.BeforeEach)
return f
}
// BeforeEach
func (f *Framework) BeforeEach() {
}
// AfterEach
func (f *Framework) AfterEach() {
}
func (f *Framework) TestWorkSpaceName() string {
if f.Workspace == "" {
f.Workspace = CreateTestWorkSpace(f.GenericClient(f.BaseName), f.BaseName)
}
return f.Workspace
}
func CreateTestWorkSpace(client client.Client, baseName string) string {
ginkgo.By("Creating a WorkSpace to execute the test in")
wspt := workspace.NewWorkspaceTemplate("", "admin")
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 workspace %s", wspt.Name))
return wspt.Name
}
func (f *Framework) GetNamespaceNames() []string {
return f.Namespaces
}
func (f *Framework) CreateNamespace(name string) string {
name = fmt.Sprintf("%s-%s", f.Workspace, name)
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: map[string]string{
constants.WorkspaceLabelKey: f.TestWorkSpaceName(),
},
},
}
opts := &client.URLOptions{
Group: "tenant.kubesphere.io",
Version: "v1alpha2",
}
err := f.GenericClient(f.BaseName).Create(context.TODO(), ns, opts, &client.WorkspaceOptions{Name: f.TestWorkSpaceName()})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return ns.Name
}
func (f *Framework) KubeSphereSystemNamespace() string {
return "Kubesphere-system"
}
func (f *Framework) GenericClient(userAgent string) client.Client {
func (f *Framework) RestClient() *rest.RESTClient {
ctx := TestContext
config := &rest.Config{
Host: ctx.Host,
Username: ctx.Username,
Password: ctx.Password,
ContentConfig: rest.ContentConfig{
ContentType: runtime.ContentTypeJSON,
NegotiatedSerializer: scheme.Codecs.WithoutConversion(),
ContentType: runtime.ContentTypeJSON,
},
}
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)
c, err := rest.UnversionedRESTClientFor(config)
if err != nil {
panic(err)
}
return c
}
func (f *Framework) GetScheme() *runtime.Scheme {
return f.Scheme
}

View File

@@ -1,19 +1,3 @@
/*
Copyright 2020 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 ginkgowrapper wraps Ginkgo Fail and Skip functions to panic
// with structured data instead of a constant string.
package ginkgowrapper
@@ -26,7 +10,7 @@ import (
"runtime/debug"
"strings"
"github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/v2"
)
// FailurePanic is the value that will be panicked from Fail.
@@ -38,7 +22,7 @@ type FailurePanic struct {
}
// String makes FailurePanic look like the old Ginkgo panic when printed.
func (FailurePanic) String() string { return ginkgo.GINKGO_PANIC }
func (p FailurePanic) String() string { return p.Message }
// Fail wraps ginkgo.Fail so that it panics with more useful
// information about the failure. This function will panic with a

View File

@@ -1,94 +0,0 @@
/*
Copyright 2020 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"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
"kubesphere.io/client-go/client"
)
var URLOptions = client.URLOptions{
Group: "iam.kubesphere.io",
Version: "v1alpha2",
}
// NewUser returns a User spec with the specified argument.
func NewUser(name, globelRole string) *iamv1alpha2.User {
return &iamv1alpha2.User{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Annotations: map[string]string{
"iam.kubesphere.io/globalrole": globelRole,
},
},
Spec: iamv1alpha2.UserSpec{
Email: fmt.Sprintf("%s@kubesphere.io", name),
EncryptedPassword: "P@88w0rd",
},
}
}
// CreateUser uses c to create User. If the returned error is nil, the returned User is valid and has
// been created.
func CreateUser(c client.Client, u *iamv1alpha2.User) (*iamv1alpha2.User, error) {
err := c.Create(context.TODO(), u, &URLOptions)
return u, err
}
// GetUser uses c to get the User by name. If the returned error is nil, the returned User is valid.
func GetUser(c client.Client, name string) (*iamv1alpha2.User, error) {
u := &iamv1alpha2.User{}
err := c.Get(context.TODO(), client.ObjectKey{Name: name}, u, &URLOptions)
if err != nil {
return nil, err
}
return u, nil
}
// NewGroup returns a Group spec with the specified argument.
func NewGroup(name, workspace string) *iamv1alpha2.Group {
return &iamv1alpha2.Group{
ObjectMeta: metav1.ObjectMeta{
GenerateName: name,
},
}
}
// CreateGroup uses c to create Group. If the returned error is nil, the returned Group is valid and has
// been created.
func CreateGroup(c client.Client, u *iamv1alpha2.Group, workspace string) (*iamv1alpha2.Group, error) {
err := c.Create(context.TODO(), u, &URLOptions, &client.WorkspaceOptions{Name: workspace})
return u, err
}
// GetGroup uses c to get the User by name. If the returned error is nil, the returned User is valid.
func GetGroup(c client.Client, name, workspace string) (*iamv1alpha2.Group, error) {
u := &iamv1alpha2.Group{}
err := c.Get(context.TODO(), client.ObjectKey{Name: name}, u, &URLOptions, &client.WorkspaceOptions{Name: workspace})
if err != nil {
return nil, err
}
return u, nil
}

View File

@@ -1,51 +0,0 @@
/*
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 (
"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
config := &rest.Config{
Host: ctx.Host,
Username: user,
Password: passsword,
}
return generic.New(config, client.Options{Scheme: s})
}
func NewRestClient(user, passsword string) (*restclient.RestClient, error) {
ctx := framework.TestContext
config := &rest.Config{
Host: ctx.Host,
Username: user,
Password: passsword,
}
return restclient.NewForConfig(config)
}

View File

@@ -1,19 +1,3 @@
/*
Copyright 2020 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 framework
import (
@@ -23,7 +7,7 @@ import (
"runtime/debug"
"time"
"github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/v2"
"kubesphere.io/kubesphere/test/e2e/framework/ginkgowrapper"
)

View File

@@ -1,35 +0,0 @@
/*
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
}

View File

@@ -1,19 +1,3 @@
/*
Copyright 2020 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 framework
import (
@@ -41,10 +25,9 @@ func registerFlags(t *TestContextType) {
"Password to login to KubeSphere API Server")
}
var TestContext *TestContextType = &TestContextType{}
var TestContext = &TestContextType{}
func setDefaultValue(t *TestContextType) {
if t.Host == "" {
t.Host = constant.LocalAPIServer
}

View File

@@ -1,94 +0,0 @@
/*
Copyright 2020 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 workspace
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
tenantv1alpha1 "kubesphere.io/api/tenant/v1alpha1"
tenantv1alpha2 "kubesphere.io/api/tenant/v1alpha2"
fedb1 "kubesphere.io/api/types/v1beta1"
"context"
"kubesphere.io/client-go/client"
)
var URLOptions = client.URLOptions{
Group: "tenant.kubesphere.io",
Version: "v1alpha2",
}
// NewWorkspaceTemplate returns a WorkspaceTemplate spec with the specified argument.
func NewWorkspaceTemplate(name string, manager string, hosts ...string) *tenantv1alpha2.WorkspaceTemplate {
clusters := []fedb1.GenericClusterReference{}
for _, h := range hosts {
clusters = append(clusters, fedb1.GenericClusterReference{Name: h})
}
return &tenantv1alpha2.WorkspaceTemplate{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: fedb1.FederatedWorkspaceSpec{
Placement: fedb1.GenericPlacementFields{
Clusters: clusters,
},
Template: fedb1.WorkspaceTemplate{
Spec: tenantv1alpha1.WorkspaceSpec{
Manager: manager,
},
},
},
}
}
// CreateWorkSpace uses c to create Workspace. If the returned error is nil, the returned Workspace is valid and has
// been created.
func CreateWorkspace(c client.Client, w *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
opts := &client.URLOptions{
AbsPath: "kapis/tenant.kubesphere.io/v1alpha2/workspaces",
}
err := c.Create(context.TODO(), w, opts)
return w, err
}
// GetJob uses c to get the Workspace by name. If the returned error is nil, the returned Workspace is valid.
func GetWorkspace(c client.Client, name string) (*tenantv1alpha1.Workspace, error) {
wsp := &tenantv1alpha1.Workspace{}
err := c.Get(context.TODO(), client.ObjectKey{Name: name}, wsp, &URLOptions)
if err != nil {
return nil, err
}
return wsp, nil
}
// DeleteWorkspace uses c to delete the Workspace by name. If the returned error is nil, the returned Workspace is valid.
func DeleteWorkspace(c client.Client, name string, opts ...client.DeleteOption) (*tenantv1alpha1.Workspace, error) {
wsp := &tenantv1alpha1.Workspace{
ObjectMeta: metav1.ObjectMeta{Name: name},
}
opts = append(opts, &URLOptions)
err := c.Delete(context.TODO(), wsp, opts...)
if err != nil {
return nil, err
}
return wsp, nil
}

View File

@@ -1,139 +0,0 @@
/*
Copyright 2020 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 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/api/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/utils/stringutils"
"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"
)
const (
GroupName = "test-group"
UserName = "tester"
)
var _ = Describe("Groups", func() {
f := framework.NewKubeSphereFramework("group")
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)
Eventually(func() bool {
user, err := iam.GetUser(adminClient, UserName)
return err == nil && stringutils.FindString(user.Spec.Groups, group) != -1
}, timeout, interval).Should(BeTrue())
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)
})
})
})
// 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
}
// 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
}
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 == "" {
return false, nil
}
return u.Status.State == v1alpha2.UserActive, nil
})
if err != nil {
return nil, err
}
return u, nil
}

View File

@@ -3,60 +3,30 @@ package e2e
import (
"context"
. "github.com/onsi/ginkgo" //nolint:stylecheck
. "github.com/onsi/gomega" //nolint:stylecheck
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"kubesphere.io/client-go/client"
"kubesphere.io/client-go/rest"
. "github.com/onsi/ginkgo/v2" //nolint:stylecheck
. "github.com/onsi/gomega" //nolint:stylecheck
"kubesphere.io/kubesphere/test/e2e/framework"
"kubesphere.io/kubesphere/test/e2e/framework/workspace"
)
var _ = Describe("API Test", func() {
f := framework.NewKubeSphereFramework("worksspace")
var gclient client.Client
f := framework.NewKubeSphereFramework()
var client *rest.RESTClient
BeforeEach(func() {
gclient = f.GenericClient("worksspace")
client = f.RestClient()
})
It("Should list Kubernetes objects through ks proxy", func() {
results := &corev1.NamespaceList{}
It("Should retrieve KubeSphere API version", func() {
result := client.Get().AbsPath("/version").Do(context.Background())
Expect(result.Error()).Should(BeNil())
Expect(gclient.List(context.TODO(), results)).Should(Succeed())
data, err := result.Raw()
Expect(err).Should(BeNil())
if len(results.Items) < 1 {
framework.Failf("Test Failed caused no Cluster role was found")
}
framework.Logf("Response is %v", results)
})
It("Should get Kubernetes objects through ks proxy", func() {
deploy := &appsv1.Deployment{}
Expect(gclient.Get(context.TODO(), client.ObjectKey{Namespace: "kubesphere-system", Name: "ks-apiserver"}, deploy)).Should(Succeed())
Expect(deploy.Name).To(Equal("ks-apiserver"))
})
It("Should list Kubernetes objects through ksapi", func() {
results := &corev1.NamespaceList{}
opts := workspace.URLOptions
err := gclient.List(context.TODO(), results, &opts)
framework.ExpectNoError(err)
framework.Logf("Response is %v", results)
})
It("Should list Kubernetes objects through ksapi by workspaces", func() {
results := &corev1.NamespaceList{}
opts := workspace.URLOptions
err := gclient.List(context.TODO(), results, &opts, &client.WorkspaceOptions{Name: "kubesphere-system"})
framework.ExpectNoError(err)
framework.Logf("Response is %v", results)
framework.Logf("Response is %v", string(data))
})
})

59
test/e2e/users.go Normal file
View File

@@ -0,0 +1,59 @@
package e2e
import (
"context"
"fmt"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
"kubesphere.io/client-go/rest"
"kubesphere.io/kubesphere/test/e2e/framework"
)
var _ = Describe("User", func() {
f := framework.NewKubeSphereFramework()
userName := "test"
var client *rest.RESTClient
BeforeEach(func() {
client = f.RestClient()
})
It("Create user", func() {
By(fmt.Sprintf("Expecting to user %s does not exists", userName))
user := &iamv1beta1.User{}
err := client.Get().
Prefix("/apis").
Group("iam.kubesphere.io").
Version("v1alpha2").
Resource("users").
Name(userName).
Do(context.Background()).
Into(user)
Expect(err).ShouldNot(BeNil())
user = &iamv1beta1.User{
ObjectMeta: v1.ObjectMeta{Name: userName},
}
err = client.Post().
Prefix("/apis").
Group("iam.kubesphere.io").
Version("v1alpha2").
Resource("users").
Body(user).
Do(context.Background()).
Into(user)
Expect(err).Should(BeNil())
Expect(user.ResourceVersion).ShouldNot(BeEmpty())
framework.Logf("User created successfully")
})
})

View File

@@ -1,74 +0,0 @@
/*
Copyright 2020 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 e2e
import (
"context"
"time"
. "github.com/onsi/ginkgo" //nolint:stylecheck
. "github.com/onsi/gomega"
"kubesphere.io/client-go/client"
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
"kubesphere.io/kubesphere/test/e2e/framework"
"kubesphere.io/kubesphere/test/e2e/framework/iam"
"kubesphere.io/kubesphere/test/e2e/framework/workspace"
)
const timeout = time.Second * 30
const interval = time.Second * 1
var _ = Describe("Worksspace", func() {
f := framework.NewKubeSphereFramework("worksspace")
var wsName = ""
var gclient client.Client
BeforeEach(func() {
gclient = f.GenericClient("worksspace")
})
It("Should create workspace and initial workspace settings", func() {
By("Expecting to create workspace thronght workspace template")
wsName = f.TestWorkSpaceName()
By("Expecting to create workspace successfully")
Eventually(func() bool {
wsp, err := workspace.GetWorkspace(gclient, wsName)
return err == nil && wsp.Name == wsName
}, timeout, interval).Should(BeTrue())
By("Expecting initial workspace roles successfully")
wspr := &iamv1alpha2.WorkspaceRoleList{}
Eventually(func() bool {
opts := iam.URLOptions
err := gclient.List(context.TODO(), wspr, &opts)
return err == nil && len(wspr.Items) > 0
}, timeout, interval).Should(BeTrue())
_, err := workspace.DeleteWorkspace(gclient, wsName)
framework.ExpectNoError(err)
framework.Logf("Workspace created successfully")
})
})