265 lines
7.7 KiB
Go
265 lines
7.7 KiB
Go
/*
|
|
*
|
|
* 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 tenant
|
|
|
|
import (
|
|
core "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/client-go/informers"
|
|
"k8s.io/client-go/kubernetes"
|
|
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
|
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
|
"kubesphere.io/kubesphere/pkg/constants"
|
|
"kubesphere.io/kubesphere/pkg/db"
|
|
"kubesphere.io/kubesphere/pkg/models/devops"
|
|
"kubesphere.io/kubesphere/pkg/models/iam/am"
|
|
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
|
"kubesphere.io/kubesphere/pkg/server/params"
|
|
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
|
|
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
|
"strings"
|
|
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
|
|
iamapi "kubesphere.io/kubesphere/pkg/api/iam"
|
|
)
|
|
|
|
type InWorkspaceUser struct {
|
|
*iamapi.User
|
|
WorkspaceRole string `json:"workspaceRole"`
|
|
}
|
|
|
|
type WorkspaceInterface interface {
|
|
GetWorkspace(workspace string) (*v1alpha1.Workspace, error)
|
|
SearchWorkspace(username string, conditions *params.Conditions, orderBy string, reverse bool) ([]*v1alpha1.Workspace, error)
|
|
ListNamespaces(workspace string) ([]*core.Namespace, error)
|
|
DeleteNamespace(workspace, namespace string) error
|
|
RemoveUser(user, workspace string) error
|
|
AddUser(workspace string, user *InWorkspaceUser) error
|
|
CountDevopsProjectsInWorkspace(workspace string) (int, error)
|
|
CountUsersInWorkspace(workspace string) (int, error)
|
|
CountOrgRoles() (int, error)
|
|
CountWorkspaces() (int, error)
|
|
CountNamespacesInWorkspace(workspace string) (int, error)
|
|
}
|
|
|
|
type workspaceOperator struct {
|
|
client kubernetes.Interface
|
|
informers informers.SharedInformerFactory
|
|
ksInformers externalversions.SharedInformerFactory
|
|
am am.AccessManagementInterface
|
|
|
|
// TODO: use db interface instead of mysql client
|
|
// we can refactor this after rewrite devops using crd
|
|
db *mysql.Database
|
|
}
|
|
|
|
func newWorkspaceOperator(client kubernetes.Interface, informers informers.SharedInformerFactory, ksinformers externalversions.SharedInformerFactory, am am.AccessManagementInterface, db *mysql.Database) WorkspaceInterface {
|
|
return &workspaceOperator{
|
|
client: client,
|
|
informers: informers,
|
|
ksInformers: ksinformers,
|
|
am: am,
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
func (w *workspaceOperator) ListNamespaces(workspace string) ([]*core.Namespace, error) {
|
|
namespaces, err := w.informers.Core().V1().Namespaces().Lister().List(labels.SelectorFromSet(labels.Set{constants.WorkspaceLabelKey: workspace}))
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return namespaces, nil
|
|
}
|
|
|
|
func (w *workspaceOperator) DeleteNamespace(workspace string, namespace string) error {
|
|
ns, err := w.informers.Core().V1().Namespaces().Lister().Get(namespace)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if ns.Labels[constants.WorkspaceLabelKey] == workspace {
|
|
deletePolicy := metav1.DeletePropagationBackground
|
|
return w.client.CoreV1().Namespaces().Delete(namespace, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
|
} else {
|
|
return apierrors.NewNotFound(schema.GroupResource{Group: "", Resource: "workspace"}, workspace)
|
|
}
|
|
}
|
|
|
|
func (w *workspaceOperator) RemoveUser(workspace string, username string) error {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (w *workspaceOperator) AddUser(workspaceName string, user *InWorkspaceUser) error {
|
|
|
|
panic("implement me")
|
|
}
|
|
|
|
func (w *workspaceOperator) CountDevopsProjectsInWorkspace(workspaceName string) (int, error) {
|
|
query := w.db.Select(devops.DevOpsProjectIdColumn).
|
|
From(devops.DevOpsProjectTableName).
|
|
Where(db.And(db.Eq(devops.DevOpsProjectWorkSpaceColumn, workspaceName),
|
|
db.Eq(devops.StatusColumn, devops.StatusActive)))
|
|
|
|
devOpsProjects := make([]string, 0)
|
|
|
|
if _, err := query.Load(&devOpsProjects); err != nil {
|
|
return 0, err
|
|
}
|
|
return len(devOpsProjects), nil
|
|
}
|
|
|
|
func (w *workspaceOperator) CountUsersInWorkspace(workspace string) (int, error) {
|
|
count, err := w.CountUsersInWorkspace(workspace)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
func (w *workspaceOperator) CountOrgRoles() (int, error) {
|
|
return len(constants.WorkSpaceRoles), nil
|
|
}
|
|
|
|
func (w *workspaceOperator) CountNamespacesInWorkspace(workspace string) (int, error) {
|
|
ns, err := w.ListNamespaces(workspace)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return len(ns), nil
|
|
}
|
|
|
|
func (*workspaceOperator) match(match map[string]string, item *v1alpha1.Workspace) bool {
|
|
for k, v := range match {
|
|
switch k {
|
|
case v1alpha2.Name:
|
|
names := strings.Split(v, "|")
|
|
if !sliceutil.HasString(names, item.Name) {
|
|
return false
|
|
}
|
|
case v1alpha2.Keyword:
|
|
if !strings.Contains(item.Name, v) && !contains(item.Labels, "", v) && !contains(item.Annotations, "", v) {
|
|
return false
|
|
}
|
|
default:
|
|
// label not exist or value not equal
|
|
if val, ok := item.Labels[k]; !ok || val != v {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (*workspaceOperator) fuzzy(fuzzy map[string]string, item *v1alpha1.Workspace) bool {
|
|
|
|
for k, v := range fuzzy {
|
|
switch k {
|
|
case v1alpha2.Name:
|
|
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
|
return false
|
|
}
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (*workspaceOperator) compare(a, b *v1alpha1.Workspace, orderBy string) bool {
|
|
switch orderBy {
|
|
case v1alpha2.CreateTime:
|
|
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
|
case v1alpha2.Name:
|
|
fallthrough
|
|
default:
|
|
return strings.Compare(a.Name, b.Name) <= 0
|
|
}
|
|
}
|
|
|
|
func (w *workspaceOperator) SearchWorkspace(username string, conditions *params.Conditions, orderBy string, reverse bool) ([]*v1alpha1.Workspace, error) {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (w *workspaceOperator) GetWorkspace(workspaceName string) (*v1alpha1.Workspace, error) {
|
|
return w.ksInformers.Tenant().V1alpha1().Workspaces().Lister().Get(workspaceName)
|
|
}
|
|
|
|
func contains(m map[string]string, key, value string) bool {
|
|
for k, v := range m {
|
|
if key == "" {
|
|
if strings.Contains(k, value) || strings.Contains(v, value) {
|
|
return true
|
|
}
|
|
} else if k == key && strings.Contains(v, value) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
/*
|
|
// TODO: move to metrics package
|
|
func GetAllProjectNums() (int, error) {
|
|
namespaceLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
|
list, err := namespaceLister.List(labels.Everything())
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return len(list), nil
|
|
}
|
|
|
|
func GetAllDevOpsProjectsNums() (int, error) {
|
|
_, err := clientset.ClientSets().Devops()
|
|
if _, notEnabled := err.(clientset.ClientSetNotEnabledError); notEnabled {
|
|
return 0, err
|
|
}
|
|
|
|
dbconn, err := clientset.ClientSets().MySQL()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
query := dbconn.Select(devops.DevOpsProjectIdColumn).
|
|
From(devops.DevOpsProjectTableName).
|
|
Where(db.Eq(devops.StatusColumn, devops.StatusActive))
|
|
|
|
devOpsProjects := make([]string, 0)
|
|
|
|
if _, err := query.Load(&devOpsProjects); err != nil {
|
|
return 0, err
|
|
}
|
|
return len(devOpsProjects), nil
|
|
}
|
|
*/
|
|
|
|
func (w *workspaceOperator) CountWorkspaces() (int, error) {
|
|
ws, err := w.ksInformers.Tenant().V1alpha1().Workspaces().Lister().List(labels.Everything())
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return len(ws), nil
|
|
}
|