diff --git a/pkg/apis/v1alpha/workspaces/workspaces.go b/pkg/apis/v1alpha/workspaces/workspaces.go index 905de7bc031d5506b855c595e085d235f1f1f3ca..19ece09a8748bc33e9fbd0c5beaf56242a60a1cc 100644 --- a/pkg/apis/v1alpha/workspaces/workspaces.go +++ b/pkg/apis/v1alpha/workspaces/workspaces.go @@ -15,6 +15,8 @@ import ( "regexp" + "sort" + "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/models/iam" "kubesphere.io/kubesphere/pkg/models/metrics" @@ -452,14 +454,26 @@ func UserWorkspaceListHandler(req *restful.Request, resp *restful.Response) { keyword := req.QueryParameter("keyword") username := req.HeaderParameter(UserNameHeader) - list, err := workspaces.ListWorkspaceByUser(username, keyword) + ws, err := workspaces.ListWorkspaceByUser(username, keyword) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()}) return } - resp.WriteEntity(list) + sort.Slice(ws, func(i, j int) bool { + t1, err := ws[i].GetCreateTime() + if err != nil { + return false + } + t2, err := ws[j].GetCreateTime() + if err != nil { + return true + } + return t1.After(t2) + }) + + resp.WriteEntity(ws) } func UserNamespaceListHandler(req *restful.Request, resp *restful.Response) { diff --git a/pkg/app/app.go b/pkg/app/app.go index 25c2e9f681c1c469009f1441932baf1b52619be2..3005ee6c2a54c5de60c2a6409439f33235e2f478 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -22,7 +22,6 @@ import ( "github.com/emicklei/go-restful" "github.com/golang/glog" - "k8s.io/api/core/v1" metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" "net" @@ -38,6 +37,8 @@ import ( "sync" "syscall" + "k8s.io/api/core/v1" + _ "kubesphere.io/kubesphere/pkg/apis/v1alpha" "kubesphere.io/kubesphere/pkg/client" "kubesphere.io/kubesphere/pkg/constants" @@ -74,36 +75,42 @@ func newKubeSphereServer(options *options.ServerRunOptions) *kubeSphereServer { func preCheck() error { k8sClient := client.NewK8sClient() _, err := k8sClient.CoreV1().Namespaces().Get(constants.KubeSphereControlNamespace, metaV1.GetOptions{}) - if err != nil && !errors.IsNotFound(err) { - return err - } - - if errors.IsNotFound(err) { - namespace := v1.Namespace{ObjectMeta: metaV1.ObjectMeta{Name: constants.KubeSphereControlNamespace}} - _, err = k8sClient.CoreV1().Namespaces().Create(&namespace) - if err != nil { + if err != nil { + if errors.IsNotFound(err) { + _, err = k8sClient.CoreV1().Namespaces().Create(&v1.Namespace{ObjectMeta: metaV1.ObjectMeta{Name: constants.KubeSphereControlNamespace}}) + if err != nil { + return err + } + } else { return err } } _, err = k8sClient.AppsV1().Deployments(constants.KubeSphereControlNamespace).Get(constants.AdminUserName, metaV1.GetOptions{}) - if errors.IsNotFound(err) { - models.CreateKubeConfig(constants.AdminUserName) - models.CreateKubectlDeploy(constants.AdminUserName) - return nil + if err != nil { + if errors.IsNotFound(err) { + if err = models.CreateKubeConfig(constants.AdminUserName); err != nil { + return err + } + if err = models.CreateKubectlDeploy(constants.AdminUserName); err != nil { + return err + } + } else { + return err + } } db := client.NewSharedDBClient() defer db.Close() - if !db.HasTable(&workspaces.WorkspaceNSBinding{}) { - db.CreateTable(&workspaces.WorkspaceNSBinding{}) - } if !db.HasTable(&workspaces.WorkspaceDPBinding{}) { - db.CreateTable(&workspaces.WorkspaceDPBinding{}) + if err := db.CreateTable(&workspaces.WorkspaceDPBinding{}).Error; err != nil { + return err + } } - return err + + return nil } func registerSwagger() { diff --git a/pkg/models/controllers/clusterrole_bindings.go b/pkg/models/controllers/clusterrole_bindings.go index a561d0804e148d14c849f791d47640b9e33cf2c4..c0285724081201835de450d7565732a84ff52acb 100644 --- a/pkg/models/controllers/clusterrole_bindings.go +++ b/pkg/models/controllers/clusterrole_bindings.go @@ -50,7 +50,7 @@ func (ctl *ClusterRoleBindingCtl) total() int { } func (ctl *ClusterRoleBindingCtl) handleWorkspaceRoleChange(clusterRole *rbac.ClusterRoleBinding) { - if groups := regexp.MustCompile("^system:(\\w+):(admin|operator|viewer)$").FindStringSubmatch(clusterRole.Name); len(groups) == 3 { + if groups := regexp.MustCompile(`^system:(\S+):(admin|operator|viewer)$`).FindStringSubmatch(clusterRole.Name); len(groups) == 3 { workspace := groups[1] go ctl.restNamespaceRoleBinding(workspace) } diff --git a/pkg/models/workspaces/types.go b/pkg/models/workspaces/types.go index edc8176c4c818d44b515e2e1ebc28ce98b5e24f0..7e3a85905d4030ef3e53da1ed068830e10de3ac1 100644 --- a/pkg/models/workspaces/types.go +++ b/pkg/models/workspaces/types.go @@ -26,9 +26,8 @@ type Group struct { Description string `json:"description"` } -type WorkspaceNSBinding struct { - Workspace string `gorm:"primary_key"` - Namespace string `gorm:"primary_key"` +func (g Group) GetCreateTime() (time.Time, error) { + return time.Parse("2006-01-02T15:04:05Z", g.CreateTime) } type WorkspaceDPBinding struct { diff --git a/pkg/models/workspaces/workspaces.go b/pkg/models/workspaces/workspaces.go index 773ba708b72d6fc6bb713a403094d48fa7b5089a..8dd34124277fa103425597ba0958eaf8b4e52b0e 100644 --- a/pkg/models/workspaces/workspaces.go +++ b/pkg/models/workspaces/workspaces.go @@ -119,7 +119,7 @@ func createDefaultDevopsRoleBinding(workspace string, project DevopsProject) { admins := iam.GetWorkspaceUsers(workspace, "admin") for _, admin := range admins { - createDevopsRoleBinding(workspace, *project.ProjectId, admin, "maintainer") + createDevopsRoleBinding(workspace, *project.ProjectId, admin, "owner") } viewers := iam.GetWorkspaceUsers(workspace, "viewer") @@ -402,7 +402,11 @@ func Create(workspace *Workspace) (*Workspace, error) { created.Namespaces = make([]string, 0) created.DevopsProjects = make([]string, 0) - go WorkspaceRoleInit(workspace) + err = WorkspaceRoleInit(workspace) + + if err != nil { + return nil, err + } return &created, nil } @@ -512,7 +516,7 @@ func ListWorkspaceByUser(username string, keyword string) ([]*Workspace, error) } else { workspaceNames := make([]string, 0) for _, clusterRole := range clusterRoles { - if groups := regexp.MustCompile(`^system:(\w+):(admin|operator|viewer)$`).FindStringSubmatch(clusterRole.Name); len(groups) == 3 { + if groups := regexp.MustCompile(`^system:(\S+):(admin|operator|viewer)$`).FindStringSubmatch(clusterRole.Name); len(groups) == 3 { if !slice.ContainsString(workspaceNames, groups[1], nil) { workspaceNames = append(workspaceNames, groups[1]) } @@ -710,7 +714,14 @@ func convertGroupToWorkspace(db *gorm.DB, group Group) (*Workspace, error) { } func CreateNamespace(namespace *core.Namespace) (*core.Namespace, error) { - return client.NewK8sClient().CoreV1().Namespaces().Create(namespace) + + ns, err := client.NewK8sClient().CoreV1().Namespaces().Create(namespace) + + if err != nil { + return nil, err + } + + return ns, nil } func Invite(workspaceName string, users []UserInvite) error { @@ -1157,7 +1168,7 @@ func CreateWorkspaceRoleBinding(workspace *Workspace, username string, role stri modify = true roleBinding.Subjects = append(roleBinding.Subjects, v1.Subject{Kind: v1.UserKind, Name: username}) if roleName == "admin" { - go createDevopsRoleBinding(workspace.Name, "", username, "maintainer") + go createDevopsRoleBinding(workspace.Name, "", username, "owner") } else if roleName == "viewer" { go createDevopsRoleBinding(workspace.Name, "", username, "reporter") }