add ks-iam and ks-apigateway
Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
@@ -18,47 +18,27 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"time"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
|
||||
"github.com/golang/glog"
|
||||
coreV1 "k8s.io/api/core/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
)
|
||||
|
||||
type Component struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
SelfLink string `json:"selfLink"`
|
||||
Label interface{} `json:"label"`
|
||||
StartedAt time.Time `json:"startedAt"`
|
||||
TotalBackends int `json:"totalBackends"`
|
||||
HealthyBackends int `json:"healthyBackends"`
|
||||
}
|
||||
|
||||
var (
|
||||
componentStatusLister lister.ComponentStatusLister
|
||||
serviceLister lister.ServiceLister
|
||||
podLister lister.PodLister
|
||||
nodeLister lister.NodeLister
|
||||
)
|
||||
|
||||
func init() {
|
||||
componentStatusLister = informers.SharedInformerFactory().Core().V1().ComponentStatuses().Lister()
|
||||
serviceLister = informers.SharedInformerFactory().Core().V1().Services().Lister()
|
||||
podLister = informers.SharedInformerFactory().Core().V1().Pods().Lister()
|
||||
nodeLister = informers.SharedInformerFactory().Core().V1().Nodes().Lister()
|
||||
}
|
||||
|
||||
func GetComponentStatus(name string) (interface{}, error) {
|
||||
|
||||
var service *coreV1.Service
|
||||
var service *corev1.Service
|
||||
var err error
|
||||
|
||||
serviceLister := informers.SharedInformerFactory().Core().V1().Services().Lister()
|
||||
|
||||
for _, ns := range constants.SystemNamespaces {
|
||||
service, err = serviceLister.Services(ns).Get(name)
|
||||
if err == nil {
|
||||
@@ -70,13 +50,15 @@ func GetComponentStatus(name string) (interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
podLister := informers.SharedInformerFactory().Core().V1().Pods().Lister()
|
||||
|
||||
pods, err := podLister.Pods(service.Namespace).List(labels.SelectorFromValidatedSet(service.Spec.Selector))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
component := Component{
|
||||
component := models.Component{
|
||||
Name: service.Name,
|
||||
Namespace: service.Namespace,
|
||||
SelfLink: service.SelfLink,
|
||||
@@ -102,11 +84,11 @@ func GetSystemHealthStatus() (map[string]interface{}, error) {
|
||||
|
||||
status := make(map[string]interface{})
|
||||
|
||||
componentStatuses, err := componentStatusLister.List(labels.Everything())
|
||||
componentStatuses, err := client.K8sClient().CoreV1().ComponentStatuses().List(meta_v1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, cs := range componentStatuses {
|
||||
for _, cs := range componentStatuses.Items {
|
||||
status[cs.Name] = cs.Conditions[0]
|
||||
}
|
||||
|
||||
@@ -119,6 +101,8 @@ func GetSystemHealthStatus() (map[string]interface{}, error) {
|
||||
for k, v := range systemComponentStatus {
|
||||
status[k] = v
|
||||
}
|
||||
|
||||
nodeLister := informers.SharedInformerFactory().Core().V1().Nodes().Lister()
|
||||
// get node status
|
||||
nodes, err := nodeLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
@@ -132,7 +116,7 @@ func GetSystemHealthStatus() (map[string]interface{}, error) {
|
||||
for _, nodes := range nodes {
|
||||
totalNodes++
|
||||
for _, condition := range nodes.Status.Conditions {
|
||||
if condition.Type == coreV1.NodeReady && condition.Status == coreV1.ConditionTrue {
|
||||
if condition.Type == corev1.NodeReady && condition.Status == corev1.ConditionTrue {
|
||||
healthyNodes++
|
||||
}
|
||||
}
|
||||
@@ -147,11 +131,12 @@ func GetSystemHealthStatus() (map[string]interface{}, error) {
|
||||
}
|
||||
|
||||
func GetAllComponentsStatus() (map[string]interface{}, error) {
|
||||
serviceLister := informers.SharedInformerFactory().Core().V1().Services().Lister()
|
||||
podLister := informers.SharedInformerFactory().Core().V1().Pods().Lister()
|
||||
|
||||
status := make(map[string]interface{})
|
||||
|
||||
var err error
|
||||
|
||||
for _, ns := range constants.SystemNamespaces {
|
||||
|
||||
nsStatus := make(map[string]interface{})
|
||||
@@ -164,7 +149,7 @@ func GetAllComponentsStatus() (map[string]interface{}, error) {
|
||||
}
|
||||
|
||||
for _, service := range services {
|
||||
component := Component{
|
||||
component := models.Component{
|
||||
Name: service.Name,
|
||||
Namespace: service.Namespace,
|
||||
SelfLink: service.SelfLink,
|
||||
|
||||
822
pkg/models/iam/am.go
Normal file
822
pkg/models/iam/am.go
Normal file
@@ -0,0 +1,822 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 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 iam
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"log"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-ldap/ldap"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/api/rbac/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam/policy"
|
||||
)
|
||||
|
||||
func GetNamespaces(username string) ([]*corev1.Namespace, error) {
|
||||
|
||||
roles, err := GetRoles(username, "")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
namespaces := make([]*corev1.Namespace, 0)
|
||||
namespaceLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
for _, role := range roles {
|
||||
namespace, err := namespaceLister.Get(role.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
namespaces = append(namespaces, namespace)
|
||||
}
|
||||
|
||||
return namespaces, nil
|
||||
}
|
||||
|
||||
func GetNamespacesByWorkspace(workspace string) ([]*corev1.Namespace, error) {
|
||||
namespaceLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
return namespaceLister.List(labels.SelectorFromSet(labels.Set{"kubesphere.io/workspace": workspace}))
|
||||
}
|
||||
|
||||
func GetDevopsRole(projectId string, username string) (string, error) {
|
||||
|
||||
//Hard fix
|
||||
if username == "admin" {
|
||||
return "owner", nil
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s/api/v1alpha/projects/%s/members", constants.DevopsAPIServer, projectId), nil)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set(constants.UserNameHeader, username)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.StatusCode > 200 {
|
||||
return "", errors.New(string(data))
|
||||
}
|
||||
|
||||
var result []map[string]string
|
||||
|
||||
err = json.Unmarshal(data, &result)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, item := range result {
|
||||
if item["username"] == username {
|
||||
return item["role"], nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func GetNamespace(namespaceName string) (*corev1.Namespace, error) {
|
||||
namespaceLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
return namespaceLister.Get(namespaceName)
|
||||
}
|
||||
|
||||
func GetRoles(username string, namespace string) ([]*v1.Role, error) {
|
||||
clusterRoleLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister()
|
||||
roleBindingLister := informers.SharedInformerFactory().Rbac().V1().RoleBindings().Lister()
|
||||
roleLister := informers.SharedInformerFactory().Rbac().V1().Roles().Lister()
|
||||
roleBindings, err := roleBindingLister.RoleBindings(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles := make([]*v1.Role, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
|
||||
for _, subject := range roleBinding.Subjects {
|
||||
if subject.Kind == v1.UserKind && subject.Name == username {
|
||||
if roleBinding.RoleRef.Kind == ClusterRoleKind {
|
||||
clusterRole, err := clusterRoleLister.Get(roleBinding.RoleRef.Name)
|
||||
if err == nil {
|
||||
var role = v1.Role{TypeMeta: (*clusterRole).TypeMeta, ObjectMeta: (*clusterRole).ObjectMeta, Rules: (*clusterRole).Rules}
|
||||
role.Namespace = roleBinding.Namespace
|
||||
roles = append(roles, &role)
|
||||
break
|
||||
} else if apierrors.IsNotFound(err) {
|
||||
log.Println(err)
|
||||
break
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if subject.Kind == v1.UserKind && subject.Name == username {
|
||||
rule, err := roleLister.Roles(roleBinding.Namespace).Get(roleBinding.RoleRef.Name)
|
||||
if err == nil {
|
||||
roles = append(roles, rule)
|
||||
break
|
||||
} else if apierrors.IsNotFound(err) {
|
||||
log.Println(err)
|
||||
break
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
func GetClusterRoles(username string) ([]*v1.ClusterRole, error) {
|
||||
clusterRoleLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister()
|
||||
clusterRoleBindingLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister()
|
||||
clusterRoleBindings, err := clusterRoleBindingLister.List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles := make([]*v1.ClusterRole, 0)
|
||||
|
||||
for _, rb := range clusterRoleBindings {
|
||||
if rb.RoleRef.Kind == ClusterRoleKind {
|
||||
for _, subject := range rb.Subjects {
|
||||
if subject.Kind == v1.UserKind && subject.Name == username {
|
||||
|
||||
role, err := clusterRoleLister.Get(rb.RoleRef.Name)
|
||||
role = role.DeepCopy()
|
||||
if err == nil {
|
||||
if role.Annotations == nil {
|
||||
role.Annotations = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
role.Annotations["rbac.authorization.k8s.io/clusterrolebinding"] = rb.Name
|
||||
|
||||
if rb.Annotations != nil &&
|
||||
rb.Annotations["rbac.authorization.k8s.io/clusterrole"] == rb.RoleRef.Name {
|
||||
role.Annotations["rbac.authorization.k8s.io/clusterrole"] = "true"
|
||||
}
|
||||
|
||||
roles = append(roles, role)
|
||||
break
|
||||
} else if apierrors.IsNotFound(err) {
|
||||
log.Println(err)
|
||||
break
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
func GetRoleBindings(namespace string, roleName string) ([]*v1.RoleBinding, error) {
|
||||
roleBindingLister := informers.SharedInformerFactory().Rbac().V1().RoleBindings().Lister()
|
||||
roleBindingList, err := roleBindingLister.List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]*v1.RoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindingList {
|
||||
if roleName == "" {
|
||||
items = append(items, roleBinding)
|
||||
} else if roleBinding.RoleRef.Name == roleName {
|
||||
items = append(items, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func GetClusterRoleBindings(clusterRoleName string) ([]*v1.ClusterRoleBinding, error) {
|
||||
clusterRoleBindingLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister()
|
||||
roleBindingList, err := clusterRoleBindingLister.List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]*v1.ClusterRoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindingList {
|
||||
if roleBinding.RoleRef.Name == clusterRoleName {
|
||||
items = append(items, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func ClusterRoleUsers(clusterRoleName string) ([]*models.User, error) {
|
||||
|
||||
roleBindings, err := GetClusterRoleBindings(clusterRoleName)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn, err := NewConnection()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
names := make([]string, 0)
|
||||
users := make([]*models.User, 0)
|
||||
for _, roleBinding := range roleBindings {
|
||||
for _, subject := range roleBinding.Subjects {
|
||||
if subject.Kind == v1.UserKind && !strings.HasPrefix(subject.Name, "system") &&
|
||||
!slice.ContainsString(names, subject.Name, nil) {
|
||||
names = append(names, subject.Name)
|
||||
|
||||
user, err := UserDetail(subject.Name, conn)
|
||||
|
||||
if ldap.IsErrorWithCode(err, 32) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
users = append(users, user)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return users, nil
|
||||
|
||||
}
|
||||
|
||||
func RoleUsers(namespace string, roleName string) ([]*models.User, error) {
|
||||
roleBindings, err := GetRoleBindings(namespace, roleName)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn, err := NewConnection()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
names := make([]string, 0)
|
||||
users := make([]*models.User, 0)
|
||||
for _, roleBinding := range roleBindings {
|
||||
for _, subject := range roleBinding.Subjects {
|
||||
if subject.Kind == v1.UserKind &&
|
||||
!strings.HasPrefix(subject.Name, "system") &&
|
||||
!slice.ContainsString(names, subject.Name, nil) {
|
||||
names = append(names, subject.Name)
|
||||
user, err := UserDetail(subject.Name, conn)
|
||||
if ldap.IsErrorWithCode(err, 32) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
users = append(users, user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func NamespaceUsers(namespaceName string) ([]*models.User, error) {
|
||||
roleBindings, err := GetRoleBindings(namespaceName, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn, err := NewConnection()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
names := make([]string, 0)
|
||||
users := make([]*models.User, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
|
||||
for _, subject := range roleBinding.Subjects {
|
||||
if subject.Kind == v1.UserKind &&
|
||||
!slice.ContainsString(names, subject.Name, nil) &&
|
||||
!strings.HasPrefix(subject.Name, "system") {
|
||||
if roleBinding.Name == "viewer" {
|
||||
continue
|
||||
}
|
||||
if roleBinding.Name == "admin" {
|
||||
continue
|
||||
}
|
||||
names = append(names, subject.Name)
|
||||
user, err := UserDetail(subject.Name, conn)
|
||||
if ldap.IsErrorWithCode(err, 32) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user.Role = roleBinding.RoleRef.Name
|
||||
user.RoleBinding = roleBinding.Name
|
||||
users = append(users, user)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func GetWorkspaceRoles(clusterRoles []*v1.ClusterRole) map[string]string {
|
||||
|
||||
workspaceRoles := make(map[string]string, 0)
|
||||
|
||||
for _, v := range clusterRoles {
|
||||
if groups := regexp.MustCompile(fmt.Sprintf(`^system:(\S+):(%s)$`, strings.Join(constants.WorkSpaceRoles, "|"))).FindStringSubmatch(v.Name); len(groups) == 3 {
|
||||
workspaceRoles[groups[1]] = groups[2]
|
||||
}
|
||||
}
|
||||
|
||||
return workspaceRoles
|
||||
}
|
||||
|
||||
func GetWorkspaceRole(clusterRoles []*v1.ClusterRole, workspace string) string {
|
||||
|
||||
for _, v := range clusterRoles {
|
||||
if groups := regexp.MustCompile(fmt.Sprintf(`^system:(\S+):(%s)$`, strings.Join(constants.WorkSpaceRoles, "|"))).FindStringSubmatch(v.Name); len(groups) == 3 {
|
||||
if groups[1] == workspace {
|
||||
return groups[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetWorkspaceSimpleRules(clusterRoles []*v1.ClusterRole, workspace string) map[string][]models.SimpleRule {
|
||||
|
||||
workspaceRules := make(map[string][]models.SimpleRule, 0)
|
||||
|
||||
clusterSimpleRules := make([]models.SimpleRule, 0)
|
||||
clusterRules := make([]v1.PolicyRule, 0)
|
||||
for _, clusterRole := range clusterRoles {
|
||||
clusterRules = append(clusterRules, clusterRole.Rules...)
|
||||
}
|
||||
|
||||
for i := 0; i < len(policy.WorkspaceRoleRuleMapping); i++ {
|
||||
rule := models.SimpleRule{Name: policy.WorkspaceRoleRuleMapping[i].Name}
|
||||
rule.Actions = make([]string, 0)
|
||||
for j := 0; j < (len(policy.WorkspaceRoleRuleMapping[i].Actions)); j++ {
|
||||
if RulesMatchesAction(clusterRules, policy.WorkspaceRoleRuleMapping[i].Actions[j]) {
|
||||
rule.Actions = append(rule.Actions, policy.WorkspaceRoleRuleMapping[i].Actions[j].Name)
|
||||
}
|
||||
}
|
||||
if len(rule.Actions) > 0 {
|
||||
clusterSimpleRules = append(clusterSimpleRules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
if len(clusterRules) > 0 {
|
||||
workspaceRules["*"] = clusterSimpleRules
|
||||
}
|
||||
|
||||
for _, v := range clusterRoles {
|
||||
|
||||
if groups := regexp.MustCompile(fmt.Sprintf(`^system:(\S+):(%s)$`, strings.Join(constants.WorkSpaceRoles, "|"))).FindStringSubmatch(v.Name); len(groups) == 3 {
|
||||
|
||||
if workspace != "" && groups[1] != workspace {
|
||||
continue
|
||||
}
|
||||
|
||||
policyRules := make([]v1.PolicyRule, 0)
|
||||
|
||||
for _, rule := range v.Rules {
|
||||
rule.ResourceNames = nil
|
||||
policyRules = append(policyRules, rule)
|
||||
}
|
||||
|
||||
rules := make([]models.SimpleRule, 0)
|
||||
|
||||
for i := 0; i < len(policy.WorkspaceRoleRuleMapping); i++ {
|
||||
rule := models.SimpleRule{Name: policy.WorkspaceRoleRuleMapping[i].Name}
|
||||
rule.Actions = make([]string, 0)
|
||||
for j := 0; j < (len(policy.WorkspaceRoleRuleMapping[i].Actions)); j++ {
|
||||
action := policy.WorkspaceRoleRuleMapping[i].Actions[j]
|
||||
if RulesMatchesAction(policyRules, action) {
|
||||
rule.Actions = append(rule.Actions, action.Name)
|
||||
}
|
||||
}
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
workspaceRules[groups[1]] = merge(rules, clusterSimpleRules)
|
||||
}
|
||||
}
|
||||
|
||||
return workspaceRules
|
||||
}
|
||||
|
||||
func merge(clusterRules, rules []models.SimpleRule) []models.SimpleRule {
|
||||
for _, clusterRule := range clusterRules {
|
||||
exist := false
|
||||
|
||||
for i := 0; i < len(rules); i++ {
|
||||
if rules[i].Name == clusterRule.Name {
|
||||
exist = true
|
||||
|
||||
for _, action := range clusterRule.Actions {
|
||||
if !slice.ContainsString(rules[i].Actions, action, nil) {
|
||||
rules[i].Actions = append(rules[i].Actions, action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !exist {
|
||||
rules = append(rules, clusterRule)
|
||||
}
|
||||
}
|
||||
return rules
|
||||
}
|
||||
|
||||
// Convert cluster roles to rules
|
||||
func GetClusterRoleSimpleRules(clusterRoles []*v1.ClusterRole) ([]models.SimpleRule, error) {
|
||||
|
||||
clusterRules := make([]v1.PolicyRule, 0)
|
||||
|
||||
for _, v := range clusterRoles {
|
||||
clusterRules = append(clusterRules, v.Rules...)
|
||||
}
|
||||
|
||||
rules := make([]models.SimpleRule, 0)
|
||||
|
||||
for i := 0; i < len(policy.ClusterRoleRuleMapping); i++ {
|
||||
validActions := make([]string, 0)
|
||||
for j := 0; j < (len(policy.ClusterRoleRuleMapping[i].Actions)); j++ {
|
||||
if RulesMatchesAction(clusterRules, policy.ClusterRoleRuleMapping[i].Actions[j]) {
|
||||
validActions = append(validActions, policy.ClusterRoleRuleMapping[i].Actions[j].Name)
|
||||
}
|
||||
}
|
||||
if len(validActions) > 0 {
|
||||
rules = append(rules, models.SimpleRule{Name: policy.ClusterRoleRuleMapping[i].Name, Actions: validActions})
|
||||
}
|
||||
}
|
||||
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
// Convert roles to rules
|
||||
func GetRoleSimpleRules(roles []*v1.Role, namespace string) (map[string][]models.SimpleRule, error) {
|
||||
|
||||
rulesMapping := make(map[string][]models.SimpleRule, 0)
|
||||
|
||||
policyRulesMapping := make(map[string][]v1.PolicyRule, 0)
|
||||
|
||||
for _, v := range roles {
|
||||
|
||||
if namespace != "" && v.Namespace != namespace {
|
||||
continue
|
||||
}
|
||||
|
||||
policyRules := policyRulesMapping[v.Namespace]
|
||||
|
||||
if policyRules == nil {
|
||||
policyRules = make([]v1.PolicyRule, 0)
|
||||
}
|
||||
|
||||
policyRules = append(policyRules, v.Rules...)
|
||||
|
||||
policyRulesMapping[v.Namespace] = policyRules
|
||||
}
|
||||
|
||||
for namespace, policyRules := range policyRulesMapping {
|
||||
|
||||
rules := make([]models.SimpleRule, 0)
|
||||
|
||||
for i := 0; i < len(policy.RoleRuleMapping); i++ {
|
||||
rule := models.SimpleRule{Name: policy.RoleRuleMapping[i].Name}
|
||||
rule.Actions = make([]string, 0)
|
||||
for j := 0; j < len(policy.RoleRuleMapping[i].Actions); j++ {
|
||||
if RulesMatchesAction(policyRules, policy.RoleRuleMapping[i].Actions[j]) {
|
||||
rule.Actions = append(rule.Actions, policy.RoleRuleMapping[i].Actions[j].Name)
|
||||
}
|
||||
}
|
||||
if len(rule.Actions) > 0 {
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
rulesMapping[namespace] = rules
|
||||
}
|
||||
|
||||
return rulesMapping, nil
|
||||
}
|
||||
|
||||
func CreateClusterRoleBinding(username string, clusterRoleName string) error {
|
||||
clusterRoleLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister()
|
||||
_, err := clusterRoleLister.Get(clusterRoleName)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clusterRoles, err := GetClusterRoles(username)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, clusterRole := range clusterRoles {
|
||||
|
||||
if clusterRole.Annotations["rbac.authorization.k8s.io/clusterrole"] == "true" {
|
||||
|
||||
if clusterRole.Name == clusterRoleName {
|
||||
return nil
|
||||
}
|
||||
|
||||
clusterRoleBindingName := clusterRole.Annotations["rbac.authorization.k8s.io/clusterrolebinding"]
|
||||
clusterRoleBindingLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister()
|
||||
clusterRoleBinding, err := clusterRoleBindingLister.Get(clusterRoleBindingName)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, v := range clusterRoleBinding.Subjects {
|
||||
if v.Kind == v1.UserKind && v.Name == username {
|
||||
clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects[:i], clusterRoleBinding.Subjects[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
_, err = client.K8sClient().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
clusterRoleBindingLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister()
|
||||
clusterRoleBindings, err := clusterRoleBindingLister.List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var clusterRoleBinding *v1.ClusterRoleBinding
|
||||
|
||||
for _, roleBinding := range clusterRoleBindings {
|
||||
if roleBinding.Annotations != nil && roleBinding.Annotations["rbac.authorization.k8s.io/clusterrole"] == clusterRoleName &&
|
||||
roleBinding.RoleRef.Name == clusterRoleName {
|
||||
clusterRoleBinding = roleBinding
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if clusterRoleBinding != nil {
|
||||
clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, v1.Subject{Kind: v1.UserKind, Name: username})
|
||||
_, err := client.K8sClient().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
clusterRoleBinding = new(v1.ClusterRoleBinding)
|
||||
clusterRoleBinding.Annotations = map[string]string{"rbac.authorization.k8s.io/clusterrole": clusterRoleName}
|
||||
clusterRoleBinding.Name = clusterRoleName
|
||||
clusterRoleBinding.RoleRef = v1.RoleRef{Name: clusterRoleName, Kind: ClusterRoleKind}
|
||||
clusterRoleBinding.Subjects = []v1.Subject{{Kind: v1.UserKind, Name: username}}
|
||||
|
||||
_, err = client.K8sClient().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetRole(namespace string, roleName string) (*v1.Role, error) {
|
||||
return informers.SharedInformerFactory().Rbac().V1().Roles().Lister().Roles(namespace).Get(roleName)
|
||||
}
|
||||
func GetClusterRole(clusterRoleName string) (*v1.ClusterRole, error) {
|
||||
clusterRoleLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister()
|
||||
return clusterRoleLister.Get(clusterRoleName)
|
||||
}
|
||||
|
||||
func RulesMatchesAction(rules []v1.PolicyRule, action models.Action) bool {
|
||||
|
||||
for _, required := range action.Rules {
|
||||
if !rulesMatchesRequired(rules, required) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func rulesMatchesRequired(rules []v1.PolicyRule, required v1.PolicyRule) bool {
|
||||
for _, rule := range rules {
|
||||
if ruleMatchesRequired(rule, required) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ruleMatchesRequired(rule v1.PolicyRule, required v1.PolicyRule) bool {
|
||||
|
||||
if len(required.NonResourceURLs) == 0 {
|
||||
for _, apiGroup := range required.APIGroups {
|
||||
for _, resource := range required.Resources {
|
||||
resources := strings.Split(resource, "/")
|
||||
resource = resources[0]
|
||||
var subsource string
|
||||
if len(resources) > 1 {
|
||||
subsource = resources[1]
|
||||
}
|
||||
|
||||
if len(required.ResourceNames) == 0 {
|
||||
for _, verb := range required.Verbs {
|
||||
if !ruleMatchesRequest(rule, apiGroup, "", resource, subsource, "", verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, resourceName := range required.ResourceNames {
|
||||
for _, verb := range required.Verbs {
|
||||
if !ruleMatchesRequest(rule, apiGroup, "", resource, subsource, resourceName, verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, apiGroup := range required.APIGroups {
|
||||
for _, nonResourceURL := range required.NonResourceURLs {
|
||||
for _, verb := range required.Verbs {
|
||||
if !ruleMatchesRequest(rule, apiGroup, nonResourceURL, "", "", "", verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ruleMatchesResources(rule v1.PolicyRule, apiGroup string, resource string, subresource string, resourceName string) bool {
|
||||
|
||||
if resource == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if !hasString(rule.APIGroups, apiGroup) && !hasString(rule.APIGroups, v1.ResourceAll) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(rule.ResourceNames) > 0 && !hasString(rule.ResourceNames, resourceName) {
|
||||
return false
|
||||
}
|
||||
|
||||
combinedResource := resource
|
||||
|
||||
if subresource != "" {
|
||||
combinedResource = combinedResource + "/" + subresource
|
||||
}
|
||||
|
||||
for _, res := range rule.Resources {
|
||||
|
||||
// match "*"
|
||||
if res == v1.ResourceAll || res == combinedResource {
|
||||
return true
|
||||
}
|
||||
|
||||
// match "*/subresource"
|
||||
if len(subresource) > 0 && strings.HasPrefix(res, "*/") && subresource == strings.TrimLeft(res, "*/") {
|
||||
return true
|
||||
}
|
||||
// match "resource/*"
|
||||
if strings.HasSuffix(res, "/*") && resource == strings.TrimRight(res, "/*") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ruleMatchesRequest(rule v1.PolicyRule, apiGroup string, nonResourceURL string, resource string, subresource string, resourceName string, verb string) bool {
|
||||
|
||||
if !hasString(rule.Verbs, verb) && !hasString(rule.Verbs, v1.VerbAll) {
|
||||
return false
|
||||
}
|
||||
|
||||
if nonResourceURL == "" {
|
||||
return ruleMatchesResources(rule, apiGroup, resource, subresource, resourceName)
|
||||
} else {
|
||||
return ruleMatchesNonResource(rule, nonResourceURL)
|
||||
}
|
||||
}
|
||||
|
||||
func ruleMatchesNonResource(rule v1.PolicyRule, nonResourceURL string) bool {
|
||||
|
||||
if nonResourceURL == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, spec := range rule.NonResourceURLs {
|
||||
if pathMatches(nonResourceURL, spec) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func pathMatches(path, spec string) bool {
|
||||
// Allow wildcard match
|
||||
if spec == "*" {
|
||||
return true
|
||||
}
|
||||
// Allow exact match
|
||||
if spec == path {
|
||||
return true
|
||||
}
|
||||
// Allow a trailing * subpath match
|
||||
if strings.HasSuffix(spec, "*") && strings.HasPrefix(path, strings.TrimRight(spec, "*")) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hasString(slice []string, value string) bool {
|
||||
for _, s := range slice {
|
||||
if s == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -15,15 +15,40 @@
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
package hpa
|
||||
package iam
|
||||
|
||||
import (
|
||||
"k8s.io/api/autoscaling/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
import "sync"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
func GetHPA(namespace, hpa string) (*v1.HorizontalPodAutoscaler, error) {
|
||||
return client.K8sClient().AutoscalingV1().HorizontalPodAutoscalers(namespace).Get(hpa, metaV1.GetOptions{})
|
||||
type Counter struct {
|
||||
value int
|
||||
m *sync.Mutex
|
||||
}
|
||||
|
||||
func NewCounter(value int) Counter {
|
||||
c := Counter{}
|
||||
c.m = &sync.Mutex{}
|
||||
c.Set(value)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Counter) Set(value int) {
|
||||
c.m.Lock()
|
||||
c.value = value
|
||||
c.m.Unlock()
|
||||
}
|
||||
|
||||
func (c *Counter) Add(value int) {
|
||||
c.m.Lock()
|
||||
c.value += value
|
||||
c.m.Unlock()
|
||||
}
|
||||
|
||||
func (c *Counter) Sub(value int) {
|
||||
c.m.Lock()
|
||||
c.value -= value
|
||||
c.m.Unlock()
|
||||
}
|
||||
|
||||
func (c *Counter) Get() int {
|
||||
return c.value
|
||||
}
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 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 iam
|
||||
|
||||
import (
|
||||
@@ -7,38 +24,22 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
v12 "k8s.io/client-go/listers/rbac/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/rbac/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
ksErr "kubesphere.io/kubesphere/pkg/errors"
|
||||
kserr "kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
)
|
||||
|
||||
const ClusterRoleKind = "ClusterRole"
|
||||
|
||||
var (
|
||||
clusterRoleBindingLister v12.ClusterRoleBindingLister
|
||||
clusterRoleLister v12.ClusterRoleLister
|
||||
roleBindingLister v12.RoleBindingLister
|
||||
roleLister v12.RoleLister
|
||||
)
|
||||
|
||||
func init() {
|
||||
clusterRoleBindingLister = informers.SharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister()
|
||||
clusterRoleLister = informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister()
|
||||
roleBindingLister = informers.SharedInformerFactory().Rbac().V1().RoleBindings().Lister()
|
||||
roleLister = informers.SharedInformerFactory().Rbac().V1().Roles().Lister()
|
||||
}
|
||||
|
||||
// Get user list based on workspace role
|
||||
func WorkspaceRoleUsers(workspace string, roleName string) ([]User, error) {
|
||||
func WorkspaceRoleUsers(workspace string, roleName string) ([]models.User, error) {
|
||||
|
||||
clusterRoleBindingLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister()
|
||||
|
||||
workspaceRoleBinding, err := clusterRoleBindingLister.Get(fmt.Sprintf("system:%s:%s", workspace, roleName))
|
||||
|
||||
@@ -67,11 +68,11 @@ func WorkspaceRoleUsers(workspace string, roleName string) ([]User, error) {
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func GetUsers(names []string) ([]User, error) {
|
||||
var users []User
|
||||
func GetUsers(names []string) ([]models.User, error) {
|
||||
var users []models.User
|
||||
|
||||
if names == nil || len(names) == 0 {
|
||||
return make([]User, 0), nil
|
||||
return make([]models.User, 0), nil
|
||||
}
|
||||
|
||||
result, err := http.Get(fmt.Sprintf("http://%s/apis/account.kubesphere.io/v1alpha1/users?name=%s", constants.AccountAPIServer, strings.Join(names, ",")))
|
||||
@@ -88,7 +89,7 @@ func GetUsers(names []string) ([]User, error) {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return nil, ksErr.Wrap(data)
|
||||
return nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &users)
|
||||
@@ -100,7 +101,7 @@ func GetUsers(names []string) ([]User, error) {
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func GetUser(name string) (*User, error) {
|
||||
func GetUser(name string) (*models.User, error) {
|
||||
|
||||
result, err := http.Get(fmt.Sprintf("http://%s/apis/account.kubesphere.io/v1alpha1/users/%s", constants.AccountAPIServer, name))
|
||||
|
||||
@@ -116,10 +117,10 @@ func GetUser(name string) (*User, error) {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return nil, ksErr.Wrap(data)
|
||||
return nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
var user User
|
||||
var user models.User
|
||||
|
||||
err = json.Unmarshal(data, &user)
|
||||
|
||||
@@ -187,16 +188,8 @@ func GetUserNamespaces(username string, requiredRule v1.PolicyRule) (allNamespac
|
||||
return false, namespaces, nil
|
||||
}
|
||||
|
||||
func GetRole(namespace string, name string) (*v1.Role, error) {
|
||||
role, err := roleLister.Roles(namespace).Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return role.DeepCopy(), nil
|
||||
}
|
||||
|
||||
func GetWorkspaceUsers(workspace string, workspaceRole string) ([]string, error) {
|
||||
clusterRoleBindingLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister()
|
||||
clusterRoleBinding, err := clusterRoleBindingLister.Get(fmt.Sprintf("system:%s:%s", workspace, workspaceRole))
|
||||
|
||||
if err != nil {
|
||||
@@ -213,108 +206,6 @@ func GetWorkspaceUsers(workspace string, workspaceRole string) ([]string, error)
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func GetClusterRole(name string) (*v1.ClusterRole, error) {
|
||||
|
||||
role, err := clusterRoleLister.Get(name)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return role.DeepCopy(), nil
|
||||
}
|
||||
|
||||
func GetRoles(namespace string, username string) ([]v1.Role, error) {
|
||||
roleBindings, err := roleBindingLister.RoleBindings(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles := make([]v1.Role, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
|
||||
for _, subject := range roleBinding.Subjects {
|
||||
if subject.Kind == v1.UserKind && subject.Name == username {
|
||||
if roleBinding.RoleRef.Kind == ClusterRoleKind {
|
||||
clusterRole, err := clusterRoleLister.Get(roleBinding.RoleRef.Name)
|
||||
if err == nil {
|
||||
var role = v1.Role{TypeMeta: (*clusterRole).TypeMeta, ObjectMeta: (*clusterRole).ObjectMeta, Rules: (*clusterRole).Rules}
|
||||
role.Namespace = roleBinding.Namespace
|
||||
roles = append(roles, role)
|
||||
break
|
||||
} else if apierrors.IsNotFound(err) {
|
||||
glog.Infoln(err.Error())
|
||||
break
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
if subject.Kind == v1.UserKind && subject.Name == username {
|
||||
role, err := roleLister.Roles(roleBinding.Namespace).Get(roleBinding.RoleRef.Name)
|
||||
if err == nil {
|
||||
roles = append(roles, *role)
|
||||
break
|
||||
} else if apierrors.IsNotFound(err) {
|
||||
glog.Infoln(err.Error())
|
||||
break
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
// Get cluster roles by username
|
||||
func GetClusterRoles(username string) ([]v1.ClusterRole, error) {
|
||||
clusterRoleBindings, err := clusterRoleBindingLister.List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles := make([]v1.ClusterRole, 0)
|
||||
|
||||
for _, roleBinding := range clusterRoleBindings {
|
||||
for _, subject := range roleBinding.Subjects {
|
||||
if subject.Kind == v1.UserKind && subject.Name == username {
|
||||
if roleBinding.RoleRef.Kind == ClusterRoleKind {
|
||||
role, err := clusterRoleLister.Get(roleBinding.RoleRef.Name)
|
||||
if err == nil {
|
||||
role = role.DeepCopy()
|
||||
if role.Annotations == nil {
|
||||
role.Annotations = make(map[string]string, 0)
|
||||
}
|
||||
role.Annotations["rbac.authorization.k8s.io/clusterrolebinding"] = roleBinding.Name
|
||||
if roleBinding.Annotations != nil &&
|
||||
roleBinding.Annotations["rbac.authorization.k8s.io/clusterrole"] == roleBinding.RoleRef.Name {
|
||||
role.Annotations["rbac.authorization.k8s.io/clusterrole"] = "true"
|
||||
}
|
||||
roles = append(roles, *role)
|
||||
break
|
||||
} else if apierrors.IsNotFound(err) {
|
||||
glog.Warning(err)
|
||||
break
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
func RulesMatchesRequired(rules []v1.PolicyRule, required v1.PolicyRule) bool {
|
||||
for _, rule := range rules {
|
||||
if ruleMatchesRequired(rule, required) {
|
||||
@@ -323,139 +214,3 @@ func RulesMatchesRequired(rules []v1.PolicyRule, required v1.PolicyRule) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ruleMatchesRequired(rule v1.PolicyRule, required v1.PolicyRule) bool {
|
||||
|
||||
if len(required.NonResourceURLs) == 0 {
|
||||
for _, apiGroup := range required.APIGroups {
|
||||
for _, resource := range required.Resources {
|
||||
resources := strings.Split(resource, "/")
|
||||
resource = resources[0]
|
||||
var subsource string
|
||||
if len(resources) > 1 {
|
||||
subsource = resources[1]
|
||||
}
|
||||
|
||||
if len(required.ResourceNames) == 0 {
|
||||
for _, verb := range required.Verbs {
|
||||
if !ruleMatchesRequest(rule, apiGroup, "", resource, subsource, "", verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, resourceName := range required.ResourceNames {
|
||||
for _, verb := range required.Verbs {
|
||||
if !ruleMatchesRequest(rule, apiGroup, "", resource, subsource, resourceName, verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, apiGroup := range required.APIGroups {
|
||||
for _, nonResourceURL := range required.NonResourceURLs {
|
||||
for _, verb := range required.Verbs {
|
||||
if !ruleMatchesRequest(rule, apiGroup, nonResourceURL, "", "", "", verb) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ruleMatchesResources(rule v1.PolicyRule, apiGroup string, resource string, subresource string, resourceName string) bool {
|
||||
|
||||
if resource == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if !hasString(rule.APIGroups, apiGroup) && !hasString(rule.APIGroups, v1.ResourceAll) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(rule.ResourceNames) > 0 && !hasString(rule.ResourceNames, resourceName) {
|
||||
return false
|
||||
}
|
||||
|
||||
combinedResource := resource
|
||||
|
||||
if subresource != "" {
|
||||
combinedResource = combinedResource + "/" + subresource
|
||||
}
|
||||
|
||||
for _, res := range rule.Resources {
|
||||
|
||||
// match "*"
|
||||
if res == v1.ResourceAll || res == combinedResource {
|
||||
return true
|
||||
}
|
||||
|
||||
// match "*/subresource"
|
||||
if len(subresource) > 0 && strings.HasPrefix(res, "*/") && subresource == strings.TrimLeft(res, "*/") {
|
||||
return true
|
||||
}
|
||||
// match "resource/*"
|
||||
if strings.HasSuffix(res, "/*") && resource == strings.TrimRight(res, "/*") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ruleMatchesRequest(rule v1.PolicyRule, apiGroup string, nonResourceURL string, resource string, subresource string, resourceName string, verb string) bool {
|
||||
|
||||
if !hasString(rule.Verbs, verb) && !hasString(rule.Verbs, v1.VerbAll) {
|
||||
return false
|
||||
}
|
||||
|
||||
if nonResourceURL == "" {
|
||||
return ruleMatchesResources(rule, apiGroup, resource, subresource, resourceName)
|
||||
} else {
|
||||
return ruleMatchesNonResource(rule, nonResourceURL)
|
||||
}
|
||||
}
|
||||
|
||||
func ruleMatchesNonResource(rule v1.PolicyRule, nonResourceURL string) bool {
|
||||
|
||||
if nonResourceURL == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, spec := range rule.NonResourceURLs {
|
||||
if pathMatches(nonResourceURL, spec) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func pathMatches(path, spec string) bool {
|
||||
// Allow wildcard match
|
||||
if spec == "*" {
|
||||
return true
|
||||
}
|
||||
// Allow exact match
|
||||
if spec == path {
|
||||
return true
|
||||
}
|
||||
// Allow a trailing * subpath match
|
||||
if strings.HasSuffix(spec, "*") && strings.HasPrefix(path, strings.TrimRight(spec, "*")) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hasString(slice []string, value string) bool {
|
||||
for _, s := range slice {
|
||||
if s == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
1155
pkg/models/iam/im.go
Normal file
1155
pkg/models/iam/im.go
Normal file
File diff suppressed because it is too large
Load Diff
76
pkg/models/iam/path.go
Normal file
76
pkg/models/iam/path.go
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 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 iam
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func convertDNToPath(dn string) string {
|
||||
|
||||
paths := regexp.MustCompile("cn=[a-z0-9]([-a-z0-9]*[a-z0-9])?").FindAllString(dn, -1)
|
||||
|
||||
if len(paths) > 1 {
|
||||
for i := 0; i < len(paths); i++ {
|
||||
paths[i] = strings.Replace(paths[i], "cn=", "", 1)
|
||||
}
|
||||
for i, j := 0, len(paths)-1; i < j; i, j = i+1, j-1 {
|
||||
paths[i], paths[j] = paths[j], paths[i]
|
||||
}
|
||||
return strings.Join(paths, ":")
|
||||
} else if len(paths) == 1 {
|
||||
return strings.Replace(paths[0], "cn=", "", -1)
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func splitPath(path string) (searchBase string, cn string) {
|
||||
|
||||
paths := strings.Split(path, ":")
|
||||
length := len(paths)
|
||||
if length > 2 {
|
||||
|
||||
cn = paths[length-1]
|
||||
basePath := paths[:length-1]
|
||||
|
||||
for i := 0; i < len(basePath); i++ {
|
||||
basePath[i] = fmt.Sprintf("cn=%s", basePath[i])
|
||||
}
|
||||
|
||||
for i, j := 0, length-2; i < j; i, j = i+1, j-1 {
|
||||
basePath[i], basePath[j] = basePath[j], basePath[i]
|
||||
}
|
||||
|
||||
searchBase = fmt.Sprintf("%s,%s", strings.Join(basePath, ","), client.GroupSearchBase)
|
||||
} else if length == 2 {
|
||||
searchBase = fmt.Sprintf("cn=%s,%s", paths[0], client.GroupSearchBase)
|
||||
cn = paths[1]
|
||||
} else {
|
||||
searchBase = client.GroupSearchBase
|
||||
if paths[0] == "" {
|
||||
cn = "*"
|
||||
} else {
|
||||
cn = paths[0]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
1333
pkg/models/iam/policy/policy.go
Normal file
1333
pkg/models/iam/policy/policy.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,39 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"k8s.io/api/rbac/v1"
|
||||
)
|
||||
|
||||
type Action struct {
|
||||
Name string `json:"name"`
|
||||
Rules []v1.PolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
Name string `json:"name"`
|
||||
Actions []Action `json:"actions"`
|
||||
}
|
||||
|
||||
type SimpleRule struct {
|
||||
Name string `json:"name"`
|
||||
Actions []string `json:"actions"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Username string `json:"username"`
|
||||
Groups []string `json:"groups"`
|
||||
Password string `json:"password,omitempty"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
Description string `json:"description"`
|
||||
Email string `json:"email"`
|
||||
LastLoginTime string `json:"last_login_time"`
|
||||
Status int `json:"status"`
|
||||
ClusterRole string `json:"cluster_role"`
|
||||
ClusterRules []SimpleRule `json:"cluster_rules,omitempty"`
|
||||
Roles map[string]string `json:"roles,omitempty"`
|
||||
Rules map[string][]SimpleRule `json:"rules,omitempty"`
|
||||
Role string `json:"role,omitempty"`
|
||||
WorkspaceRoles map[string]string `json:"workspace_roles,omitempty"`
|
||||
WorkspaceRole string `json:"workspace_role,omitempty"`
|
||||
WorkspaceRules map[string][]SimpleRule `json:"workspace_rules,omitempty"`
|
||||
}
|
||||
@@ -258,7 +258,7 @@ func CreateKubeConfig(user string) error {
|
||||
configMap := v1.ConfigMap{TypeMeta: metaV1.TypeMeta{Kind: "Configmap", APIVersion: "v1"}, ObjectMeta: metaV1.ObjectMeta{Name: user}, Data: data}
|
||||
_, err = k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Create(&configMap)
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
glog.Errorf("create user %s's kubeConfig failed, reason: %s", user, err)
|
||||
glog.Errorf("create user %s's kubeConfig failed, reason: %v", user, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -271,7 +271,7 @@ func GetKubeConfig(user string) (string, error) {
|
||||
k8sClient := client.K8sClient()
|
||||
configMap, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(user, metaV1.GetOptions{})
|
||||
if err != nil {
|
||||
glog.Errorf("cannot get user %s's kubeConfig, reason: %s", user, err)
|
||||
glog.Errorf("cannot get user %s's kubeConfig, reason: %v", user, err)
|
||||
return "", err
|
||||
}
|
||||
return configMap.Data[kubectlConfigKey], nil
|
||||
@@ -287,7 +287,7 @@ func DelKubeConfig(user string) error {
|
||||
deletePolicy := metaV1.DeletePropagationBackground
|
||||
err = k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Delete(user, &metaV1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||
if err != nil {
|
||||
glog.Errorf("delete user %s's kubeConfig failed, reason: %s", user, err)
|
||||
glog.Errorf("delete user %s's kubeConfig failed, reason: %v", user, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -20,6 +20,7 @@ package kubectl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"math/rand"
|
||||
|
||||
"github.com/golang/glog"
|
||||
@@ -38,18 +39,12 @@ const (
|
||||
namespace = constants.KubeSphereControlNamespace
|
||||
)
|
||||
|
||||
type PodInfo struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Pod string `json:"pod"`
|
||||
Container string `json:"container"`
|
||||
}
|
||||
|
||||
func GetKubectlPod(username string) (PodInfo, error) {
|
||||
func GetKubectlPod(username string) (models.PodInfo, error) {
|
||||
k8sClient := client.K8sClient()
|
||||
deploy, err := k8sClient.AppsV1beta2().Deployments(namespace).Get(username, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
return PodInfo{}, err
|
||||
return models.PodInfo{}, err
|
||||
}
|
||||
|
||||
selectors := deploy.Spec.Selector.MatchLabels
|
||||
@@ -57,16 +52,16 @@ func GetKubectlPod(username string) (PodInfo, error) {
|
||||
podList, err := k8sClient.CoreV1().Pods(namespace).List(metav1.ListOptions{LabelSelector: labelSelector})
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
return PodInfo{}, err
|
||||
return models.PodInfo{}, err
|
||||
}
|
||||
|
||||
pod, err := selectCorrectPod(namespace, podList.Items)
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
return PodInfo{}, err
|
||||
return models.PodInfo{}, err
|
||||
}
|
||||
|
||||
info := PodInfo{Namespace: pod.Namespace, Pod: pod.Name, Container: pod.Status.ContainerStatuses[0].Name}
|
||||
info := models.PodInfo{Namespace: pod.Namespace, Pod: pod.Name, Container: pod.Status.ContainerStatuses[0].Name}
|
||||
|
||||
return info, nil
|
||||
|
||||
|
||||
@@ -20,14 +20,13 @@ package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
v12 "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/components"
|
||||
@@ -50,7 +49,6 @@ import (
|
||||
var (
|
||||
jsonIter = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
nodeStatusDelLabel = []string{"endpoint", "instance", "job", "namespace", "pod", "service"}
|
||||
nodeLister v12.NodeLister
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -126,10 +124,6 @@ type OneComponentStatus struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
nodeLister = informers.SharedInformerFactory().Core().V1().Nodes().Lister()
|
||||
}
|
||||
|
||||
func getAllWorkspaceNames(formatedMetric *FormatedMetric) map[string]int {
|
||||
|
||||
var wsMap = make(map[string]int)
|
||||
@@ -197,12 +191,12 @@ func unifyMetricHistoryTimeRange(fmtMetrics *FormatedMetric) {
|
||||
var timestampMap = make(map[float64]bool)
|
||||
|
||||
if fmtMetrics.Data.ResultType == ResultTypeMatrix {
|
||||
for i, _ := range fmtMetrics.Data.Result {
|
||||
for i := range fmtMetrics.Data.Result {
|
||||
values, exist := fmtMetrics.Data.Result[i][ResultItemValues]
|
||||
if exist {
|
||||
valueArray, sure := values.([]interface{})
|
||||
if sure {
|
||||
for j, _ := range valueArray {
|
||||
for j := range valueArray {
|
||||
timeAndValue := valueArray[j].([]interface{})
|
||||
timestampMap[float64(timeAndValue[0].(uint64))] = true
|
||||
}
|
||||
@@ -213,7 +207,7 @@ func unifyMetricHistoryTimeRange(fmtMetrics *FormatedMetric) {
|
||||
|
||||
timestampArray := make([]float64, len(timestampMap))
|
||||
i := 0
|
||||
for timestamp, _ := range timestampMap {
|
||||
for timestamp := range timestampMap {
|
||||
timestampArray[i] = timestamp
|
||||
i++
|
||||
}
|
||||
@@ -230,7 +224,7 @@ func unifyMetricHistoryTimeRange(fmtMetrics *FormatedMetric) {
|
||||
formatValueArray := make([][]interface{}, len(timestampArray))
|
||||
j := 0
|
||||
|
||||
for k, _ := range timestampArray {
|
||||
for k := range timestampArray {
|
||||
valueItem, sure := valueArray[j].([]interface{})
|
||||
if sure && float64(valueItem[0].(uint64)) == timestampArray[k] {
|
||||
formatValueArray[k] = []interface{}{int64(timestampArray[k]), valueItem[1]}
|
||||
@@ -294,7 +288,7 @@ func GetMetric(queryType, params, metricName string) *FormatedMetric {
|
||||
}
|
||||
|
||||
func GetNodeAddressInfo() *map[string][]v1.NodeAddress {
|
||||
|
||||
nodeLister := informers.SharedInformerFactory().Core().V1().Nodes().Lister()
|
||||
nodes, err := nodeLister.List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
@@ -938,7 +932,7 @@ func MonitorComponentStatus(monitoringRequest *client.MonitoringRequestParams) *
|
||||
nsStatus, exist := Components[ns]
|
||||
if exist {
|
||||
for _, nsStatusItem := range nsStatus.(map[string]interface{}) {
|
||||
component := nsStatusItem.(components.Component)
|
||||
component := nsStatusItem.(models.Component)
|
||||
namespaceComponentTotalMap[ns] += 1
|
||||
if component.HealthyBackends != 0 && component.HealthyBackends == component.TotalBackends {
|
||||
namespaceComponentHealthyMap[ns] += 1
|
||||
|
||||
@@ -33,7 +33,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
)
|
||||
|
||||
func DrainNode(nodename string) (err error) {
|
||||
@@ -45,7 +44,7 @@ func DrainNode(nodename string) (err error) {
|
||||
}
|
||||
|
||||
if node.Spec.Unschedulable {
|
||||
return errors.New(errors.Conflict, fmt.Sprintf("node %s have been drained", nodename))
|
||||
return fmt.Errorf("node %s have been drained", nodename)
|
||||
}
|
||||
|
||||
data := []byte(" {\"spec\":{\"unschedulable\":true}}")
|
||||
|
||||
@@ -23,10 +23,10 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
v12 "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -51,27 +51,17 @@ var (
|
||||
statefulsetsKey: resources.StatefulSets, persistentvolumeclaimsKey: resources.PersistentVolumeClaims, podsKey: resources.Pods,
|
||||
namespaceKey: resources.Namespaces, storageClassesKey: resources.StorageClasses, clusterRolesKey: resources.ClusterRoles,
|
||||
jobsKey: resources.Jobs, cronJobsKey: resources.CronJobs}
|
||||
resouceQuotaLister v12.ResourceQuotaLister
|
||||
)
|
||||
|
||||
type ResourceQuota struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Data v1.ResourceQuotaStatus `json:"data"`
|
||||
}
|
||||
|
||||
func getUsage(namespace, resource string) (int, error) {
|
||||
list, err := resources.ListNamespaceResource(namespace, resource, "", "", false, -1, 0)
|
||||
list, err := resources.ListNamespaceResource(namespace, resource, ¶ms.Conditions{}, "", false, -1, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return list.TotalCount, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
resouceQuotaLister = informers.SharedInformerFactory().Core().V1().ResourceQuotas().Lister()
|
||||
}
|
||||
|
||||
func GetClusterQuotas() (*ResourceQuota, error) {
|
||||
func GetClusterQuotas() (*models.ResourceQuota, error) {
|
||||
|
||||
quota := v1.ResourceQuotaStatus{Hard: make(v1.ResourceList), Used: make(v1.ResourceList)}
|
||||
|
||||
@@ -85,11 +75,11 @@ func GetClusterQuotas() (*ResourceQuota, error) {
|
||||
quota.Used[v1.ResourceName(k)] = quantity
|
||||
}
|
||||
|
||||
return &ResourceQuota{Namespace: "\"\"", Data: quota}, nil
|
||||
return &models.ResourceQuota{Namespace: "\"\"", Data: quota}, nil
|
||||
|
||||
}
|
||||
|
||||
func GetNamespaceQuotas(namespace string) (*ResourceQuota, error) {
|
||||
func GetNamespaceQuotas(namespace string) (*models.ResourceQuota, error) {
|
||||
quota, err := getNamespaceResourceQuota(namespace)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
@@ -115,7 +105,7 @@ func GetNamespaceQuotas(namespace string) (*ResourceQuota, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return &ResourceQuota{Namespace: namespace, Data: *quota}, nil
|
||||
return &models.ResourceQuota{Namespace: namespace, Data: *quota}, nil
|
||||
}
|
||||
|
||||
func updateNamespaceQuota(tmpResourceList, resourceList v1.ResourceList) {
|
||||
@@ -135,7 +125,8 @@ func updateNamespaceQuota(tmpResourceList, resourceList v1.ResourceList) {
|
||||
}
|
||||
|
||||
func getNamespaceResourceQuota(namespace string) (*v1.ResourceQuotaStatus, error) {
|
||||
quotaList, err := resouceQuotaLister.ResourceQuotas(namespace).List(labels.Everything())
|
||||
resourceQuotaLister := informers.SharedInformerFactory().Core().V1().ResourceQuotas().Lister()
|
||||
quotaList, err := resourceQuotaLister.ResourceQuotas(namespace).List(labels.Everything())
|
||||
if err != nil || len(quotaList) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -20,12 +20,11 @@ package registries
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/golang/glog"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
)
|
||||
|
||||
type AuthInfo struct {
|
||||
@@ -62,6 +61,6 @@ func RegistryVerify(authInfo AuthInfo) error {
|
||||
if resp.Status == loginSuccess {
|
||||
return nil
|
||||
} else {
|
||||
return errors.New(errors.VerifyFailed, resp.Status)
|
||||
return fmt.Errorf(resp.Status)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/listers/rbac/v1"
|
||||
)
|
||||
|
||||
type clusterRoleSearcher struct {
|
||||
clusterRoleLister v1.ClusterRoleLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*clusterRoleSearcher) match(match map[string]string, item *rbac.ClusterRole) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -45,7 +45,7 @@ func (*clusterRoleSearcher) match(match map[string]string, item *rbac.ClusterRol
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*clusterRoleSearcher) fuzzy(fuzzy map[string]string, item *rbac.ClusterRole) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -86,8 +86,8 @@ func (*clusterRoleSearcher) compare(a, b *rbac.ClusterRole, orderBy string) bool
|
||||
}
|
||||
}
|
||||
|
||||
func (s *clusterRoleSearcher) search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
clusterRoles, err := s.clusterRoleLister.List(labels.Everything())
|
||||
func (s *clusterRoleSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
clusterRoles, err := informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -95,11 +95,11 @@ func (s *clusterRoleSearcher) search(conditions *conditions, orderBy string, rev
|
||||
|
||||
result := make([]*rbac.ClusterRole, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = clusterRoles
|
||||
} else {
|
||||
for _, item := range clusterRoles {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,20 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type configMapSearcher struct {
|
||||
configMapLister lister.ConfigMapLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*configMapSearcher) match(match map[string]string, item *v1.ConfigMap) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -46,7 +45,7 @@ func (*configMapSearcher) match(match map[string]string, item *v1.ConfigMap) boo
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*configMapSearcher) fuzzy(fuzzy map[string]string, item *v1.ConfigMap) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -91,8 +90,8 @@ func (*configMapSearcher) compare(a, b *v1.ConfigMap, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *configMapSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
configMaps, err := s.configMapLister.ConfigMaps(namespace).List(labels.Everything())
|
||||
func (s *configMapSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
configMaps, err := informers.SharedInformerFactory().Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -100,11 +99,11 @@ func (s *configMapSearcher) search(namespace string, conditions *conditions, ord
|
||||
|
||||
result := make([]*v1.ConfigMap, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = configMaps
|
||||
} else {
|
||||
for _, item := range configMaps {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,28 +18,28 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/batch/v2alpha1"
|
||||
"k8s.io/api/batch/v1beta1"
|
||||
|
||||
"k8s.io/api/batch/v2alpha1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type cronJobSearcher struct {
|
||||
cronJobLister lister.CronJobLister
|
||||
}
|
||||
|
||||
func cronJobStatus(item *v2alpha1.CronJob) string {
|
||||
func cronJobStatus(item *v1beta1.CronJob) string {
|
||||
if item.Spec.Suspend != nil && *item.Spec.Suspend {
|
||||
return paused
|
||||
}
|
||||
return running
|
||||
}
|
||||
|
||||
// Exactly match
|
||||
func (*cronJobSearcher) match(match map[string]string, item *v2alpha1.CronJob) bool {
|
||||
// Exactly Match
|
||||
func (*cronJobSearcher) match(match map[string]string, item *v1beta1.CronJob) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case status:
|
||||
@@ -53,7 +53,7 @@ func (*cronJobSearcher) match(match map[string]string, item *v2alpha1.CronJob) b
|
||||
return true
|
||||
}
|
||||
|
||||
func (*cronJobSearcher) fuzzy(fuzzy map[string]string, item *v2alpha1.CronJob) bool {
|
||||
func (*cronJobSearcher) fuzzy(fuzzy map[string]string, item *v1beta1.CronJob) bool {
|
||||
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -88,7 +88,7 @@ func (*cronJobSearcher) fuzzy(fuzzy map[string]string, item *v2alpha1.CronJob) b
|
||||
return true
|
||||
}
|
||||
|
||||
func (*cronJobSearcher) compare(a, b *v2alpha1.CronJob, orderBy string) bool {
|
||||
func (*cronJobSearcher) compare(a, b *v1beta1.CronJob, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case createTime:
|
||||
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
|
||||
@@ -99,20 +99,20 @@ func (*cronJobSearcher) compare(a, b *v2alpha1.CronJob, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *cronJobSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
cronJobs, err := s.cronJobLister.CronJobs(namespace).List(labels.Everything())
|
||||
func (s *cronJobSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
cronJobs, err := informers.SharedInformerFactory().Batch().V1beta1().CronJobs().Lister().CronJobs(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v2alpha1.CronJob, 0)
|
||||
result := make([]*v1beta1.CronJob, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = cronJobs
|
||||
} else {
|
||||
for _, item := range cronJobs {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,16 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/apps/v1"
|
||||
|
||||
"k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type daemonSetSearcher struct {
|
||||
daemonSetLister lister.DaemonSetLister
|
||||
}
|
||||
|
||||
func daemonSetStatus(item *v1.DaemonSet) string {
|
||||
@@ -41,7 +40,7 @@ func daemonSetStatus(item *v1.DaemonSet) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Exactly match
|
||||
// Exactly Match
|
||||
func (*daemonSetSearcher) match(match map[string]string, item *v1.DaemonSet) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -102,8 +101,8 @@ func (*daemonSetSearcher) compare(a, b *v1.DaemonSet, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *daemonSetSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
daemonSets, err := s.daemonSetLister.DaemonSets(namespace).List(labels.Everything())
|
||||
func (s *daemonSetSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
daemonSets, err := informers.SharedInformerFactory().Apps().V1().DaemonSets().Lister().DaemonSets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -111,11 +110,11 @@ func (s *daemonSetSearcher) search(namespace string, conditions *conditions, ord
|
||||
|
||||
result := make([]*v1.DaemonSet, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = daemonSets
|
||||
} else {
|
||||
for _, item := range daemonSets {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,18 +18,17 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/apps/v1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"k8s.io/api/apps/v1"
|
||||
)
|
||||
|
||||
type deploymentSearcher struct {
|
||||
deploymentLister lister.DeploymentLister
|
||||
}
|
||||
|
||||
func deploymentStatus(item *v1.Deployment) string {
|
||||
@@ -45,7 +44,7 @@ func deploymentStatus(item *v1.Deployment) string {
|
||||
return stopped
|
||||
}
|
||||
|
||||
// Exactly match
|
||||
// Exactly Match
|
||||
func (*deploymentSearcher) match(match map[string]string, item *v1.Deployment) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -106,8 +105,8 @@ func (*deploymentSearcher) compare(a, b *v1.Deployment, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *deploymentSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
deployments, err := s.deploymentLister.Deployments(namespace).List(labels.Everything())
|
||||
func (s *deploymentSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
deployments, err := informers.SharedInformerFactory().Apps().V1().Deployments().Lister().Deployments(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -115,11 +114,11 @@ func (s *deploymentSearcher) search(namespace string, conditions *conditions, or
|
||||
|
||||
result := make([]*v1.Deployment, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = deployments
|
||||
} else {
|
||||
for _, item := range deployments {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,21 +18,20 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/extensions/v1beta1"
|
||||
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type ingressSearcher struct {
|
||||
ingressLister lister.IngressLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*ingressSearcher) match(match map[string]string, item *extensions.Ingress) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -47,7 +46,7 @@ func (*ingressSearcher) match(match map[string]string, item *extensions.Ingress)
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*ingressSearcher) fuzzy(fuzzy map[string]string, item *extensions.Ingress) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -92,8 +91,8 @@ func (*ingressSearcher) compare(a, b *extensions.Ingress, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ingressSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
ingresses, err := s.ingressLister.Ingresses(namespace).List(labels.Everything())
|
||||
func (s *ingressSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
ingresses, err := informers.SharedInformerFactory().Extensions().V1beta1().Ingresses().Lister().Ingresses(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -101,11 +100,11 @@ func (s *ingressSearcher) search(namespace string, conditions *conditions, order
|
||||
|
||||
result := make([]*extensions.Ingress, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = ingresses
|
||||
} else {
|
||||
for _, item := range ingresses {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,37 +18,36 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
lister "k8s.io/client-go/listers/batch/v1"
|
||||
|
||||
batchV1 "k8s.io/api/batch/v1"
|
||||
coreV1 "k8s.io/api/core/v1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type jobSearcher struct {
|
||||
jobLister lister.JobLister
|
||||
}
|
||||
|
||||
func jobStatus(item *batchV1.Job) string {
|
||||
func jobStatus(item *batchv1.Job) string {
|
||||
status := ""
|
||||
|
||||
for _, condition := range item.Status.Conditions {
|
||||
if condition.Type == batchV1.JobFailed && condition.Status == coreV1.ConditionTrue {
|
||||
if condition.Type == batchv1.JobFailed && condition.Status == corev1.ConditionTrue {
|
||||
status = failed
|
||||
}
|
||||
if condition.Type == batchV1.JobComplete && condition.Status == coreV1.ConditionTrue {
|
||||
if condition.Type == batchv1.JobComplete && condition.Status == corev1.ConditionTrue {
|
||||
status = complete
|
||||
}
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
||||
// Exactly match
|
||||
func (*jobSearcher) match(match map[string]string, item *batchV1.Job) bool {
|
||||
// Exactly Match
|
||||
func (*jobSearcher) match(match map[string]string, item *batchv1.Job) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case status:
|
||||
@@ -62,7 +61,7 @@ func (*jobSearcher) match(match map[string]string, item *batchV1.Job) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (*jobSearcher) fuzzy(fuzzy map[string]string, item *batchV1.Job) bool {
|
||||
func (*jobSearcher) fuzzy(fuzzy map[string]string, item *batchv1.Job) bool {
|
||||
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -97,7 +96,7 @@ func (*jobSearcher) fuzzy(fuzzy map[string]string, item *batchV1.Job) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func jobUpdateTime(item *batchV1.Job) time.Time {
|
||||
func jobUpdateTime(item *batchv1.Job) time.Time {
|
||||
updateTime := item.CreationTimestamp.Time
|
||||
for _, condition := range item.Status.Conditions {
|
||||
if updateTime.Before(condition.LastProbeTime.Time) {
|
||||
@@ -110,7 +109,7 @@ func jobUpdateTime(item *batchV1.Job) time.Time {
|
||||
return updateTime
|
||||
}
|
||||
|
||||
func (*jobSearcher) compare(a, b *batchV1.Job, orderBy string) bool {
|
||||
func (*jobSearcher) compare(a, b *batchv1.Job, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case updateTime:
|
||||
return jobUpdateTime(a).After(jobUpdateTime(b))
|
||||
@@ -121,20 +120,20 @@ func (*jobSearcher) compare(a, b *batchV1.Job, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *jobSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
jobs, err := s.jobLister.Jobs(namespace).List(labels.Everything())
|
||||
func (s *jobSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
jobs, err := informers.SharedInformerFactory().Batch().V1().Jobs().Lister().Jobs(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*batchV1.Job, 0)
|
||||
result := make([]*batchv1.Job, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = jobs
|
||||
} else {
|
||||
for _, item := range jobs {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
)
|
||||
|
||||
type namespaceSearcher struct {
|
||||
namespaceLister lister.NamespaceLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*namespaceSearcher) match(match map[string]string, item *v1.Namespace) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -45,7 +45,7 @@ func (*namespaceSearcher) match(match map[string]string, item *v1.Namespace) boo
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*namespaceSearcher) fuzzy(fuzzy map[string]string, item *v1.Namespace) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -90,8 +90,8 @@ func (*namespaceSearcher) compare(a, b *v1.Namespace, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *namespaceSearcher) search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
namespaces, err := s.namespaceLister.List(labels.Everything())
|
||||
func (s *namespaceSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
namespaces, err := informers.SharedInformerFactory().Core().V1().Namespaces().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -99,11 +99,11 @@ func (s *namespaceSearcher) search(conditions *conditions, orderBy string, rever
|
||||
|
||||
result := make([]*v1.Namespace, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = namespaces
|
||||
} else {
|
||||
for _, item := range namespaces {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
)
|
||||
|
||||
type nodeSearcher struct {
|
||||
nodeLister lister.NodeLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*nodeSearcher) match(match map[string]string, item *v1.Node) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -45,7 +45,7 @@ func (*nodeSearcher) match(match map[string]string, item *v1.Node) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*nodeSearcher) fuzzy(fuzzy map[string]string, item *v1.Node) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -90,8 +90,8 @@ func (*nodeSearcher) compare(a, b *v1.Node, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *nodeSearcher) search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
nodes, err := s.nodeLister.List(labels.Everything())
|
||||
func (s *nodeSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
nodes, err := informers.SharedInformerFactory().Core().V1().Nodes().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -99,11 +99,11 @@ func (s *nodeSearcher) search(conditions *conditions, orderBy string, reverse bo
|
||||
|
||||
result := make([]*v1.Node, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = nodes
|
||||
} else {
|
||||
for _, item := range nodes {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,20 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type persistentVolumeClaimSearcher struct {
|
||||
persistentVolumeClaimLister lister.PersistentVolumeClaimLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*persistentVolumeClaimSearcher) match(match map[string]string, item *v1.PersistentVolumeClaim) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -46,7 +45,7 @@ func (*persistentVolumeClaimSearcher) match(match map[string]string, item *v1.Pe
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*persistentVolumeClaimSearcher) fuzzy(fuzzy map[string]string, item *v1.PersistentVolumeClaim) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -91,8 +90,8 @@ func (*persistentVolumeClaimSearcher) compare(a, b *v1.PersistentVolumeClaim, or
|
||||
}
|
||||
}
|
||||
|
||||
func (s *persistentVolumeClaimSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
persistentVolumeClaims, err := s.persistentVolumeClaimLister.PersistentVolumeClaims(namespace).List(labels.Everything())
|
||||
func (s *persistentVolumeClaimSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
persistentVolumeClaims, err := informers.SharedInformerFactory().Core().V1().PersistentVolumeClaims().Lister().PersistentVolumeClaims(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -100,11 +99,11 @@ func (s *persistentVolumeClaimSearcher) search(namespace string, conditions *con
|
||||
|
||||
result := make([]*v1.PersistentVolumeClaim, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = persistentVolumeClaims
|
||||
} else {
|
||||
for _, item := range persistentVolumeClaims {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,20 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
v12 "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type podSearcher struct {
|
||||
podLister v12.PodLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*podSearcher) match(match map[string]string, item *v1.Pod) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -46,7 +45,7 @@ func (*podSearcher) match(match map[string]string, item *v1.Pod) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*podSearcher) fuzzy(fuzzy map[string]string, item *v1.Pod) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -91,9 +90,9 @@ func (*podSearcher) compare(a, b *v1.Pod, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *podSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
func (s *podSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
|
||||
pods, err := s.podLister.Pods(namespace).List(labels.Everything())
|
||||
pods, err := informers.SharedInformerFactory().Core().V1().Pods().Lister().Pods(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -101,11 +100,11 @@ func (s *podSearcher) search(namespace string, conditions *conditions, orderBy s
|
||||
|
||||
result := make([]*v1.Pod, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = pods
|
||||
} else {
|
||||
for _, item := range pods {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,74 +18,35 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"strings"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
namespacedResources[ConfigMaps] = &configMapSearcher{
|
||||
configMapLister: informers.SharedInformerFactory().Core().V1().ConfigMaps().Lister(),
|
||||
}
|
||||
namespacedResources[CronJobs] = &cronJobSearcher{
|
||||
cronJobLister: informers.SharedInformerFactory().Batch().V2alpha1().CronJobs().Lister(),
|
||||
}
|
||||
namespacedResources[DaemonSets] = &daemonSetSearcher{
|
||||
daemonSetLister: informers.SharedInformerFactory().Apps().V1().DaemonSets().Lister(),
|
||||
}
|
||||
namespacedResources[Deployments] = &deploymentSearcher{
|
||||
deploymentLister: informers.SharedInformerFactory().Apps().V1().Deployments().Lister(),
|
||||
}
|
||||
namespacedResources[Ingresses] = &ingressSearcher{
|
||||
ingressLister: informers.SharedInformerFactory().Extensions().V1beta1().Ingresses().Lister(),
|
||||
}
|
||||
namespacedResources[Jobs] = &jobSearcher{
|
||||
jobLister: informers.SharedInformerFactory().Batch().V1().Jobs().Lister(),
|
||||
}
|
||||
namespacedResources[PersistentVolumeClaims] = &persistentVolumeClaimSearcher{
|
||||
persistentVolumeClaimLister: informers.SharedInformerFactory().Core().V1().PersistentVolumeClaims().Lister(),
|
||||
}
|
||||
namespacedResources[Secrets] = &secretSearcher{
|
||||
secretLister: informers.SharedInformerFactory().Core().V1().Secrets().Lister(),
|
||||
}
|
||||
namespacedResources[Services] = &serviceSearcher{
|
||||
serviceLister: informers.SharedInformerFactory().Core().V1().Services().Lister(),
|
||||
}
|
||||
namespacedResources[StatefulSets] = &statefulSetSearcher{
|
||||
statefulSetLister: informers.SharedInformerFactory().Apps().V1().StatefulSets().Lister(),
|
||||
}
|
||||
namespacedResources[Pods] = &podSearcher{
|
||||
podLister: informers.SharedInformerFactory().Core().V1().Pods().Lister(),
|
||||
}
|
||||
namespacedResources[Roles] = &roleSearcher{
|
||||
roleLister: informers.SharedInformerFactory().Rbac().V1().Roles().Lister(),
|
||||
}
|
||||
namespacedResources[ConfigMaps] = &configMapSearcher{}
|
||||
namespacedResources[CronJobs] = &cronJobSearcher{}
|
||||
namespacedResources[DaemonSets] = &daemonSetSearcher{}
|
||||
namespacedResources[Deployments] = &deploymentSearcher{}
|
||||
namespacedResources[Ingresses] = &ingressSearcher{}
|
||||
namespacedResources[Jobs] = &jobSearcher{}
|
||||
namespacedResources[PersistentVolumeClaims] = &persistentVolumeClaimSearcher{}
|
||||
namespacedResources[Secrets] = &secretSearcher{}
|
||||
namespacedResources[Services] = &serviceSearcher{}
|
||||
namespacedResources[StatefulSets] = &statefulSetSearcher{}
|
||||
namespacedResources[Pods] = &podSearcher{}
|
||||
namespacedResources[Roles] = &roleSearcher{}
|
||||
|
||||
clusterResources[Nodes] = &nodeSearcher{
|
||||
nodeLister: informers.SharedInformerFactory().Core().V1().Nodes().Lister(),
|
||||
}
|
||||
clusterResources[Namespaces] = &namespaceSearcher{
|
||||
namespaceLister: informers.SharedInformerFactory().Core().V1().Namespaces().Lister(),
|
||||
}
|
||||
clusterResources[ClusterRoles] = &clusterRoleSearcher{
|
||||
clusterRoleLister: informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister(),
|
||||
}
|
||||
clusterResources[StorageClasses] = &storageClassesSearcher{
|
||||
storageClassesLister: informers.SharedInformerFactory().Storage().V1().StorageClasses().Lister(),
|
||||
}
|
||||
clusterResources[Nodes] = &nodeSearcher{}
|
||||
clusterResources[Namespaces] = &namespaceSearcher{}
|
||||
clusterResources[ClusterRoles] = &clusterRoleSearcher{}
|
||||
clusterResources[StorageClasses] = &storageClassesSearcher{}
|
||||
}
|
||||
|
||||
var namespacedResources = make(map[string]namespacedSearcherInterface)
|
||||
var clusterResources = make(map[string]clusterSearcherInterface)
|
||||
|
||||
type conditions struct {
|
||||
match map[string]string
|
||||
fuzzy map[string]string
|
||||
}
|
||||
|
||||
const (
|
||||
name = "name"
|
||||
label = "label"
|
||||
@@ -123,33 +84,26 @@ const (
|
||||
)
|
||||
|
||||
type namespacedSearcherInterface interface {
|
||||
search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error)
|
||||
search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error)
|
||||
}
|
||||
type clusterSearcherInterface interface {
|
||||
search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error)
|
||||
search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error)
|
||||
}
|
||||
|
||||
func ListNamespaceResource(namespace, resource, conditionStr, orderBy string, reverse bool, limit, offset int) (*ResourceList, error) {
|
||||
func ListNamespaceResource(namespace, resource string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
|
||||
items := make([]interface{}, 0)
|
||||
total := 0
|
||||
var err error
|
||||
|
||||
conditions, err := parseToConditions(conditionStr)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []interface{}
|
||||
|
||||
if searcher, ok := namespacedResources[resource]; ok {
|
||||
result, err = searcher.search(namespace, conditions, orderBy, reverse)
|
||||
} else {
|
||||
return nil, errors.New(errors.NotImplement, "not support")
|
||||
return nil, fmt.Errorf("not support")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New(errors.Internal, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
total = len(result)
|
||||
@@ -160,16 +114,14 @@ func ListNamespaceResource(namespace, resource, conditionStr, orderBy string, re
|
||||
}
|
||||
}
|
||||
|
||||
return &ResourceList{TotalCount: total, Items: items}, nil
|
||||
return &models.PageableResponse{TotalCount: total, Items: items}, nil
|
||||
}
|
||||
|
||||
func ListClusterResource(resource, conditionStr, orderBy string, reverse bool, limit, offset int) (*ResourceList, error) {
|
||||
func ListClusterResource(resource string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
|
||||
items := make([]interface{}, 0)
|
||||
total := 0
|
||||
var err error
|
||||
|
||||
conditions, err := parseToConditions(conditionStr)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -179,11 +131,11 @@ func ListClusterResource(resource, conditionStr, orderBy string, reverse bool, l
|
||||
if searcher, ok := clusterResources[resource]; ok {
|
||||
result, err = searcher.search(conditions, orderBy, reverse)
|
||||
} else {
|
||||
return nil, errors.New(errors.NotImplement, "not support")
|
||||
return nil, fmt.Errorf("not support")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New(errors.Internal, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
total = len(result)
|
||||
@@ -194,36 +146,7 @@ func ListClusterResource(resource, conditionStr, orderBy string, reverse bool, l
|
||||
}
|
||||
}
|
||||
|
||||
return &ResourceList{TotalCount: total, Items: items}, nil
|
||||
}
|
||||
|
||||
func parseToConditions(str string) (*conditions, error) {
|
||||
conditions := &conditions{match: make(map[string]string, 0), fuzzy: make(map[string]string, 0)}
|
||||
|
||||
if str == "" {
|
||||
return conditions, nil
|
||||
}
|
||||
|
||||
for _, item := range strings.Split(str, ",") {
|
||||
if strings.Count(item, "=") > 1 || strings.Count(item, "~") > 1 {
|
||||
return nil, errors.New(errors.InvalidArgument, "invalid condition")
|
||||
}
|
||||
if groups := regexp.MustCompile(`(\S+)([=~])(\S+)`).FindStringSubmatch(item); len(groups) == 4 {
|
||||
if groups[2] == "=" {
|
||||
conditions.match[groups[1]] = groups[3]
|
||||
} else {
|
||||
conditions.fuzzy[groups[1]] = groups[3]
|
||||
}
|
||||
} else {
|
||||
return nil, errors.New(errors.InvalidArgument, "invalid condition")
|
||||
}
|
||||
}
|
||||
return conditions, nil
|
||||
}
|
||||
|
||||
type ResourceList struct {
|
||||
TotalCount int `json:"total_count"`
|
||||
Items []interface{} `json:"items"`
|
||||
return &models.PageableResponse{TotalCount: total, Items: items}, nil
|
||||
}
|
||||
|
||||
func searchFuzzy(m map[string]string, key, value string) bool {
|
||||
|
||||
@@ -18,20 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
lister "k8s.io/client-go/listers/rbac/v1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type roleSearcher struct {
|
||||
roleLister lister.RoleLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*roleSearcher) match(match map[string]string, item *rbac.Role) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -46,7 +45,7 @@ func (*roleSearcher) match(match map[string]string, item *rbac.Role) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*roleSearcher) fuzzy(fuzzy map[string]string, item *rbac.Role) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -87,8 +86,8 @@ func (*roleSearcher) compare(a, b *rbac.Role, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *roleSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
roles, err := s.roleLister.Roles(namespace).List(labels.Everything())
|
||||
func (s *roleSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
roles, err := informers.SharedInformerFactory().Rbac().V1().Roles().Lister().Roles(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -96,11 +95,11 @@ func (s *roleSearcher) search(namespace string, conditions *conditions, orderBy
|
||||
|
||||
result := make([]*rbac.Role, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = roles
|
||||
} else {
|
||||
for _, item := range roles {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,20 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type secretSearcher struct {
|
||||
secretLister lister.SecretLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*secretSearcher) match(match map[string]string, item *v1.Secret) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -50,7 +49,7 @@ func (*secretSearcher) match(match map[string]string, item *v1.Secret) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*secretSearcher) fuzzy(fuzzy map[string]string, item *v1.Secret) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -95,8 +94,8 @@ func (*secretSearcher) compare(a, b *v1.Secret, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *secretSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
secrets, err := s.secretLister.Secrets(namespace).List(labels.Everything())
|
||||
func (s *secretSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
secrets, err := informers.SharedInformerFactory().Core().V1().Secrets().Lister().Secrets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -104,11 +103,11 @@ func (s *secretSearcher) search(namespace string, conditions *conditions, orderB
|
||||
|
||||
result := make([]*v1.Secret, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = secrets
|
||||
} else {
|
||||
for _, item := range secrets {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,20 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type serviceSearcher struct {
|
||||
serviceLister lister.ServiceLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*serviceSearcher) match(match map[string]string, item *v1.Service) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -46,7 +45,7 @@ func (*serviceSearcher) match(match map[string]string, item *v1.Service) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*serviceSearcher) fuzzy(fuzzy map[string]string, item *v1.Service) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -91,8 +90,8 @@ func (*serviceSearcher) compare(a, b *v1.Service, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *serviceSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
services, err := s.serviceLister.Services(namespace).List(labels.Everything())
|
||||
func (s *serviceSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
services, err := informers.SharedInformerFactory().Core().V1().Services().Lister().Services(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -100,11 +99,11 @@ func (s *serviceSearcher) search(namespace string, conditions *conditions, order
|
||||
|
||||
result := make([]*v1.Service, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = services
|
||||
} else {
|
||||
for _, item := range services {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,16 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lister "k8s.io/client-go/listers/apps/v1"
|
||||
|
||||
"k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type statefulSetSearcher struct {
|
||||
statefulSetLister lister.StatefulSetLister
|
||||
}
|
||||
|
||||
func statefulSetStatus(item *v1.StatefulSet) string {
|
||||
@@ -44,7 +43,7 @@ func statefulSetStatus(item *v1.StatefulSet) string {
|
||||
return stopped
|
||||
}
|
||||
|
||||
// Exactly match
|
||||
// Exactly Match
|
||||
func (*statefulSetSearcher) match(match map[string]string, item *v1.StatefulSet) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -105,8 +104,8 @@ func (*statefulSetSearcher) compare(a, b *v1.StatefulSet, orderBy string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *statefulSetSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
statefulSets, err := s.statefulSetLister.StatefulSets(namespace).List(labels.Everything())
|
||||
func (s *statefulSetSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
statefulSets, err := informers.SharedInformerFactory().Apps().V1().StatefulSets().Lister().StatefulSets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -114,11 +113,11 @@ func (s *statefulSetSearcher) search(namespace string, conditions *conditions, o
|
||||
|
||||
result := make([]*v1.StatefulSet, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = statefulSets
|
||||
} else {
|
||||
for _, item := range statefulSets {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,19 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
lister "k8s.io/client-go/listers/storage/v1"
|
||||
)
|
||||
|
||||
type storageClassesSearcher struct {
|
||||
storageClassesLister lister.StorageClassLister
|
||||
}
|
||||
|
||||
// exactly match
|
||||
// exactly Match
|
||||
func (*storageClassesSearcher) match(match map[string]string, item *v1.StorageClass) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
@@ -45,7 +45,7 @@ func (*storageClassesSearcher) match(match map[string]string, item *v1.StorageCl
|
||||
return true
|
||||
}
|
||||
|
||||
// fuzzy searchInNamespace
|
||||
// Fuzzy searchInNamespace
|
||||
func (*storageClassesSearcher) fuzzy(fuzzy map[string]string, item *v1.StorageClass) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
@@ -86,8 +86,8 @@ func (*storageClassesSearcher) compare(a, b *v1.StorageClass, orderBy string) bo
|
||||
}
|
||||
}
|
||||
|
||||
func (s *storageClassesSearcher) search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
storageClasses, err := s.storageClassesLister.List(labels.Everything())
|
||||
func (s *storageClassesSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
storageClasses, err := informers.SharedInformerFactory().Storage().V1().StorageClasses().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -95,11 +95,11 @@ func (s *storageClassesSearcher) search(conditions *conditions, orderBy string,
|
||||
|
||||
result := make([]*v1.StorageClass, 0)
|
||||
|
||||
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = storageClasses
|
||||
} else {
|
||||
for _, item := range storageClasses {
|
||||
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,29 +24,11 @@ import (
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
lister "k8s.io/client-go/listers/apps/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
)
|
||||
|
||||
var (
|
||||
daemonSetLister lister.DaemonSetLister
|
||||
deploymentLister lister.DeploymentLister
|
||||
replicaSetLister lister.ReplicaSetLister
|
||||
statefulSetLister lister.StatefulSetLister
|
||||
controllerRevisionLister lister.ControllerRevisionLister
|
||||
)
|
||||
|
||||
func init() {
|
||||
daemonSetLister = informers.SharedInformerFactory().Apps().V1().DaemonSets().Lister()
|
||||
deploymentLister = informers.SharedInformerFactory().Apps().V1().Deployments().Lister()
|
||||
replicaSetLister = informers.SharedInformerFactory().Apps().V1().ReplicaSets().Lister()
|
||||
statefulSetLister = informers.SharedInformerFactory().Apps().V1().StatefulSets().Lister()
|
||||
controllerRevisionLister = informers.SharedInformerFactory().Apps().V1().ControllerRevisions().Lister()
|
||||
}
|
||||
|
||||
func GetDeployRevision(namespace, name, revision string) (*v1.ReplicaSet, error) {
|
||||
deploymentLister := informers.SharedInformerFactory().Apps().V1().Deployments().Lister()
|
||||
deploy, err := deploymentLister.Deployments(namespace).Get(name)
|
||||
if err != nil {
|
||||
glog.Errorf("get deployment %s failed, reason: %s", name, err)
|
||||
@@ -56,6 +38,7 @@ func GetDeployRevision(namespace, name, revision string) (*v1.ReplicaSet, error)
|
||||
labelMap := deploy.Spec.Template.Labels
|
||||
labelSelector := labels.Set(labelMap).AsSelector()
|
||||
|
||||
replicaSetLister := informers.SharedInformerFactory().Apps().V1().ReplicaSets().Lister()
|
||||
rsList, err := replicaSetLister.ReplicaSets(namespace).List(labelSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -67,11 +50,11 @@ func GetDeployRevision(namespace, name, revision string) (*v1.ReplicaSet, error)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New(errors.NotFound, fmt.Sprintf("revision not found %v#%v", name, revision))
|
||||
return nil, fmt.Errorf("revision not found %v#%v", name, revision)
|
||||
}
|
||||
|
||||
func GetDaemonSetRevision(namespace, name string, revisionInt int) (*v1.ControllerRevision, error) {
|
||||
|
||||
daemonSetLister := informers.SharedInformerFactory().Apps().V1().DaemonSets().Lister()
|
||||
ds, err := daemonSetLister.DaemonSets(namespace).Get(name)
|
||||
|
||||
if err != nil {
|
||||
@@ -84,7 +67,7 @@ func GetDaemonSetRevision(namespace, name string, revisionInt int) (*v1.Controll
|
||||
}
|
||||
|
||||
func GetStatefulSetRevision(namespace, name string, revisionInt int) (*v1.ControllerRevision, error) {
|
||||
|
||||
statefulSetLister := informers.SharedInformerFactory().Apps().V1().StatefulSets().Lister()
|
||||
st, err := statefulSetLister.StatefulSets(namespace).Get(name)
|
||||
|
||||
if err != nil {
|
||||
@@ -97,7 +80,7 @@ func GetStatefulSetRevision(namespace, name string, revisionInt int) (*v1.Contro
|
||||
func getControllerRevision(namespace, name string, labelMap map[string]string, revision int) (*v1.ControllerRevision, error) {
|
||||
|
||||
labelSelector := labels.Set(labelMap).AsSelector()
|
||||
|
||||
controllerRevisionLister := informers.SharedInformerFactory().Apps().V1().ControllerRevisions().Lister()
|
||||
revisions, err := controllerRevisionLister.ControllerRevisions(namespace).List(labelSelector)
|
||||
|
||||
if err != nil {
|
||||
@@ -110,5 +93,5 @@ func getControllerRevision(namespace, name string, labelMap map[string]string, r
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New(errors.NotFound, fmt.Sprintf("revision not found %v#%v", name, revision))
|
||||
return nil, fmt.Errorf("revision not found %v#%v", name, revision)
|
||||
}
|
||||
|
||||
@@ -23,15 +23,12 @@ import (
|
||||
"io/ioutil"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
v12 "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/errors"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
|
||||
"github.com/golang/glog"
|
||||
coreV1 "k8s.io/api/core/v1"
|
||||
extensionsV1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
"k8s.io/api/rbac/v1"
|
||||
@@ -43,18 +40,10 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
)
|
||||
|
||||
var (
|
||||
serviceLister v12.ServiceLister
|
||||
)
|
||||
|
||||
func init() {
|
||||
serviceLister = informers.SharedInformerFactory().Core().V1().Services().Lister()
|
||||
}
|
||||
|
||||
func GetAllRouters() ([]*coreV1.Service, error) {
|
||||
func GetAllRouters() ([]*corev1.Service, error) {
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set{"app": "kubesphere", "component": "ks-router", "tier": "backend"})
|
||||
|
||||
serviceLister := informers.SharedInformerFactory().Core().V1().Services().Lister()
|
||||
services, err := serviceLister.Services(constants.IngressControllerNamespace).List(selector)
|
||||
|
||||
if err != nil {
|
||||
@@ -65,7 +54,7 @@ func GetAllRouters() ([]*coreV1.Service, error) {
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func GetAllRoutersOfUser(username string) ([]*coreV1.Service, error) {
|
||||
func GetAllRoutersOfUser(username string) ([]*corev1.Service, error) {
|
||||
allNamespace, namespaces, err := iam.GetUserNamespaces(username, v1.PolicyRule{
|
||||
Verbs: []string{"get", "list"},
|
||||
APIGroups: []string{""},
|
||||
@@ -82,7 +71,7 @@ func GetAllRoutersOfUser(username string) ([]*coreV1.Service, error) {
|
||||
return GetAllRouters()
|
||||
}
|
||||
|
||||
routers := make([]*coreV1.Service, 0)
|
||||
routers := make([]*corev1.Service, 0)
|
||||
|
||||
for _, namespace := range namespaces {
|
||||
router, err := GetRouter(namespace)
|
||||
@@ -99,11 +88,11 @@ func GetAllRoutersOfUser(username string) ([]*coreV1.Service, error) {
|
||||
}
|
||||
|
||||
// Get router from a namespace
|
||||
func GetRouter(namespace string) (*coreV1.Service, error) {
|
||||
func GetRouter(namespace string) (*corev1.Service, error) {
|
||||
serviceName := constants.IngressControllerPrefix + namespace
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set{"app": "kubesphere", "component": "ks-router", "tier": "backend", "project": namespace})
|
||||
|
||||
serviceLister := informers.SharedInformerFactory().Core().V1().Services().Lister()
|
||||
services, err := serviceLister.Services(constants.IngressControllerNamespace).List(selector)
|
||||
|
||||
if err != nil {
|
||||
@@ -116,7 +105,7 @@ func GetRouter(namespace string) (*coreV1.Service, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New(errors.NotFound, fmt.Sprintf("resources not found %s", serviceName))
|
||||
return nil, fmt.Errorf("resources not found %s", serviceName)
|
||||
}
|
||||
|
||||
// Load all resource yamls
|
||||
@@ -148,11 +137,11 @@ func LoadYamls() ([]string, error) {
|
||||
}
|
||||
|
||||
// Create a ingress controller in a namespace
|
||||
func CreateRouter(namespace string, routerType coreV1.ServiceType, annotations map[string]string) (*coreV1.Service, error) {
|
||||
func CreateRouter(namespace string, routerType corev1.ServiceType, annotations map[string]string) (*corev1.Service, error) {
|
||||
|
||||
k8sClient := client.K8sClient()
|
||||
|
||||
var router *coreV1.Service
|
||||
var router *corev1.Service
|
||||
|
||||
yamls, err := LoadYamls()
|
||||
|
||||
@@ -170,8 +159,8 @@ func CreateRouter(namespace string, routerType coreV1.ServiceType, annotations m
|
||||
}
|
||||
|
||||
switch obj.(type) {
|
||||
case *coreV1.Service:
|
||||
service := obj.(*coreV1.Service)
|
||||
case *corev1.Service:
|
||||
service := obj.(*corev1.Service)
|
||||
|
||||
service.SetAnnotations(annotations)
|
||||
service.Spec.Type = routerType
|
||||
@@ -190,8 +179,8 @@ func CreateRouter(namespace string, routerType coreV1.ServiceType, annotations m
|
||||
|
||||
router = service
|
||||
|
||||
case *extensionsV1beta1.Deployment:
|
||||
deployment := obj.(*extensionsV1beta1.Deployment)
|
||||
case *extensionsv1beta1.Deployment:
|
||||
deployment := obj.(*extensionsv1beta1.Deployment)
|
||||
deployment.Name = constants.IngressControllerPrefix + namespace
|
||||
|
||||
// Add project label
|
||||
@@ -204,7 +193,7 @@ func CreateRouter(namespace string, routerType coreV1.ServiceType, annotations m
|
||||
// Choose self as master
|
||||
deployment.Spec.Template.Spec.Containers[0].Args = append(deployment.Spec.Template.Spec.Containers[0].Args, "--election-id="+deployment.Name)
|
||||
|
||||
if routerType == coreV1.ServiceTypeLoadBalancer {
|
||||
if routerType == corev1.ServiceTypeLoadBalancer {
|
||||
deployment.Spec.Template.Spec.Containers[0].Args = append(deployment.Spec.Template.Spec.Containers[0].Args, "--publish-service="+constants.IngressControllerNamespace+"/"+constants.IngressControllerPrefix+namespace)
|
||||
} else {
|
||||
deployment.Spec.Template.Spec.Containers[0].Args = append(deployment.Spec.Template.Spec.Containers[0].Args, "--report-node-internal-ip-address")
|
||||
@@ -224,11 +213,11 @@ func CreateRouter(namespace string, routerType coreV1.ServiceType, annotations m
|
||||
|
||||
// DeleteRouter is used to delete ingress controller related resources in namespace
|
||||
// It will not delete ClusterRole resource cause it maybe used by other controllers
|
||||
func DeleteRouter(namespace string) (*coreV1.Service, error) {
|
||||
func DeleteRouter(namespace string) (*corev1.Service, error) {
|
||||
k8sClient := client.K8sClient()
|
||||
|
||||
var err error
|
||||
var router *coreV1.Service
|
||||
var router *corev1.Service
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
@@ -236,9 +225,9 @@ func DeleteRouter(namespace string) (*coreV1.Service, error) {
|
||||
|
||||
// delete controller service
|
||||
serviceName := constants.IngressControllerPrefix + namespace
|
||||
deleteOptions := metaV1.DeleteOptions{}
|
||||
deleteOptions := meta_v1.DeleteOptions{}
|
||||
|
||||
listOptions := metaV1.ListOptions{
|
||||
listOptions := meta_v1.ListOptions{
|
||||
LabelSelector: "app=kubesphere,component=ks-router,tier=backend,project=" + namespace,
|
||||
FieldSelector: "metadata.name=" + serviceName}
|
||||
|
||||
@@ -259,7 +248,7 @@ func DeleteRouter(namespace string) (*coreV1.Service, error) {
|
||||
// delete controller deployment
|
||||
deploymentName := constants.IngressControllerPrefix + namespace
|
||||
|
||||
listOptions = metaV1.ListOptions{
|
||||
listOptions = meta_v1.ListOptions{
|
||||
LabelSelector: "app=kubesphere,component=ks-router,tier=backend,project=" + namespace,
|
||||
}
|
||||
deployments, err := k8sClient.ExtensionsV1beta1().Deployments(constants.IngressControllerNamespace).List(listOptions)
|
||||
@@ -279,10 +268,10 @@ func DeleteRouter(namespace string) (*coreV1.Service, error) {
|
||||
}
|
||||
|
||||
// Update Ingress Controller Service, change type from NodePort to Loadbalancer or vice versa.
|
||||
func UpdateRouter(namespace string, routerType coreV1.ServiceType, annotations map[string]string) (*coreV1.Service, error) {
|
||||
func UpdateRouter(namespace string, routerType corev1.ServiceType, annotations map[string]string) (*corev1.Service, error) {
|
||||
k8sClient := client.K8sClient()
|
||||
|
||||
var router *coreV1.Service
|
||||
var router *corev1.Service
|
||||
|
||||
router, err := GetRouter(namespace)
|
||||
|
||||
@@ -293,7 +282,7 @@ func UpdateRouter(namespace string, routerType coreV1.ServiceType, annotations m
|
||||
|
||||
if router == nil {
|
||||
glog.Error("Trying to update a non-existed router")
|
||||
return nil, errors.New(errors.Internal, "router not created yet")
|
||||
return nil, fmt.Errorf("router not created yet")
|
||||
}
|
||||
|
||||
// from LoadBalancer to NodePort, or vice-versa
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
)
|
||||
@@ -31,7 +32,7 @@ type workLoadStatus struct {
|
||||
|
||||
func GetNamespacesResourceStatus(namespace string) (*workLoadStatus, error) {
|
||||
res := workLoadStatus{Count: make(map[string]int), Namespace: namespace, Items: make(map[string]interface{})}
|
||||
var notReadyList *resources.ResourceList
|
||||
var notReadyList *models.PageableResponse
|
||||
var err error
|
||||
for _, resource := range []string{resources.Deployments, resources.StatefulSets, resources.DaemonSets, resources.PersistentVolumeClaims} {
|
||||
notReadyStatus := "updating"
|
||||
@@ -39,7 +40,7 @@ func GetNamespacesResourceStatus(namespace string) (*workLoadStatus, error) {
|
||||
notReadyStatus = "pending"
|
||||
}
|
||||
|
||||
notReadyList, err = resources.ListNamespaceResource(namespace, resource, fmt.Sprintf("status=%s", notReadyStatus), "", false, -1, 0)
|
||||
notReadyList, err = resources.ListNamespaceResource(namespace, resource, ¶ms.Conditions{Match: map[string]string{"status": notReadyStatus}}, "", false, -1, 0)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -24,9 +24,6 @@ import (
|
||||
storageV1 "k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
lister2 "k8s.io/client-go/listers/storage/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
)
|
||||
|
||||
@@ -36,18 +33,12 @@ type ScMetrics struct {
|
||||
PvcNumber string `json:"pvcNumber"`
|
||||
}
|
||||
|
||||
var (
|
||||
persistentVolumeClaimLister lister.PersistentVolumeClaimLister
|
||||
persistentVolumeLister lister.PersistentVolumeLister
|
||||
sotrageClassesLister lister2.StorageClassLister
|
||||
)
|
||||
|
||||
func init() {
|
||||
persistentVolumeClaimLister = informers.SharedInformerFactory().Core().V1().PersistentVolumeClaims().Lister()
|
||||
persistentVolumeLister = informers.SharedInformerFactory().Core().V1().PersistentVolumes().Lister()
|
||||
|
||||
}
|
||||
|
||||
func GetPvcListBySc(scName string) ([]*v1.PersistentVolumeClaim, error) {
|
||||
persistentVolumeClaimLister := informers.SharedInformerFactory().Core().V1().PersistentVolumeClaims().Lister()
|
||||
all, err := persistentVolumeClaimLister.List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
@@ -70,6 +61,7 @@ func GetPvcListBySc(scName string) ([]*v1.PersistentVolumeClaim, error) {
|
||||
|
||||
// Get info of metrics
|
||||
func GetScMetrics(scName string) (*ScMetrics, error) {
|
||||
persistentVolumeLister := informers.SharedInformerFactory().Core().V1().PersistentVolumes().Lister()
|
||||
pvList, err := persistentVolumeLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -102,7 +94,7 @@ func GetScMetrics(scName string) (*ScMetrics, error) {
|
||||
func GetScList() ([]*storageV1.StorageClass, error) {
|
||||
|
||||
// Get StorageClass list
|
||||
scList, err := sotrageClassesLister.List(labels.Everything())
|
||||
scList, err := informers.SharedInformerFactory().Storage().V1().StorageClasses().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -20,19 +20,12 @@ package storage
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
v12 "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
)
|
||||
|
||||
var podLister v12.PodLister
|
||||
|
||||
func init() {
|
||||
podLister = informers.SharedInformerFactory().Core().V1().Pods().Lister()
|
||||
}
|
||||
|
||||
// List pods of a specific persistent volume claims
|
||||
func GetPodListByPvc(pvc string, ns string) (res []*v1.Pod, err error) {
|
||||
podLister := informers.SharedInformerFactory().Core().V1().Pods().Lister()
|
||||
podList, err := podLister.Pods(ns).List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -17,11 +17,121 @@
|
||||
*/
|
||||
package models
|
||||
|
||||
type MessageResponse struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
import (
|
||||
v12 "k8s.io/api/core/v1"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/rbac/v1"
|
||||
)
|
||||
|
||||
type PageableResponse struct {
|
||||
Items []interface{} `json:"items"`
|
||||
TotalCount int `json:"total_count"`
|
||||
}
|
||||
|
||||
type Workspace struct {
|
||||
Group `json:",inline"`
|
||||
Admin string `json:"admin,omitempty"`
|
||||
Namespaces []string `json:"namespaces"`
|
||||
DevopsProjects []string `json:"devops_projects"`
|
||||
}
|
||||
|
||||
type UserInvite struct {
|
||||
Username string `json:"username"`
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
func (g Group) GetCreateTime() (time.Time, error) {
|
||||
return time.Parse("2006-01-02T15:04:05Z", g.CreateTime)
|
||||
}
|
||||
|
||||
type WorkspaceDPBinding struct {
|
||||
Workspace string `gorm:"primary_key"`
|
||||
DevOpsProject string `gorm:"primary_key"`
|
||||
}
|
||||
|
||||
type DevopsProject struct {
|
||||
ProjectId *string `json:"project_id,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Creator string `json:"creator"`
|
||||
CreateTime *time.Time `json:"create_time,omitempty"`
|
||||
Status *string `json:"status"`
|
||||
Visibility *string `json:"visibility,omitempty"`
|
||||
}
|
||||
|
||||
type Action struct {
|
||||
Name string `json:"name"`
|
||||
Rules []v1.PolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
Name string `json:"name"`
|
||||
Actions []Action `json:"actions"`
|
||||
}
|
||||
|
||||
type SimpleRule struct {
|
||||
Name string `json:"name"`
|
||||
Actions []string `json:"actions"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Username string `json:"username"`
|
||||
//UID string `json:"uid"`
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
CurrentPassword string `json:"current_password,omitempty"`
|
||||
//Extra map[string]interface{} `json:"extra"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
Description string `json:"description"`
|
||||
Email string `json:"email"`
|
||||
LastLoginTime string `json:"last_login_time"`
|
||||
Status int `json:"status"`
|
||||
ClusterRole string `json:"cluster_role"`
|
||||
ClusterRules []SimpleRule `json:"cluster_rules"`
|
||||
Roles map[string]string `json:"roles,omitempty"`
|
||||
Rules map[string][]SimpleRule `json:"rules,omitempty"`
|
||||
Role string `json:"role,omitempty"`
|
||||
RoleBinding string `json:"role_binding,omitempty"`
|
||||
Lang string `json:"lang,omitempty"`
|
||||
WorkspaceRoles map[string]string `json:"workspace_roles,omitempty"`
|
||||
WorkspaceRole string `json:"workspace_role,omitempty"`
|
||||
WorkspaceRules map[string][]SimpleRule `json:"workspace_rules,omitempty"`
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Gid string `json:"gid"`
|
||||
Members []string `json:"members"`
|
||||
Logo string `json:"logo"`
|
||||
Creator string `json:"creator"`
|
||||
CreateTime string `json:"create_time"`
|
||||
ChildGroups []string `json:"child_groups"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type Component struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
SelfLink string `json:"selfLink"`
|
||||
Label interface{} `json:"label"`
|
||||
StartedAt time.Time `json:"startedAt"`
|
||||
TotalBackends int `json:"totalBackends"`
|
||||
HealthyBackends int `json:"healthyBackends"`
|
||||
}
|
||||
|
||||
type PodInfo struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Pod string `json:"pod"`
|
||||
Container string `json:"container"`
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Token string `json:"access_token"`
|
||||
}
|
||||
|
||||
type ResourceQuota struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Data v12.ResourceQuotaStatus `json:"data"`
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 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 workspaces
|
||||
|
||||
import "time"
|
||||
|
||||
type Workspace struct {
|
||||
Group `json:",inline"`
|
||||
Admin string `json:"admin,omitempty"`
|
||||
Namespaces []string `json:"namespaces"`
|
||||
DevopsProjects []string `json:"devops_projects"`
|
||||
}
|
||||
|
||||
type UserInvite struct {
|
||||
Username string `json:"username"`
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Gid string `json:"gid"`
|
||||
Members []string `json:"members"`
|
||||
Logo string `json:"logo"`
|
||||
Creator string `json:"creator"`
|
||||
CreateTime string `json:"create_time"`
|
||||
ChildGroups []string `json:"child_groups,omitempty"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
func (g Group) GetCreateTime() (time.Time, error) {
|
||||
return time.Parse("2006-01-02T15:04:05Z", g.CreateTime)
|
||||
}
|
||||
|
||||
type WorkspaceDPBinding struct {
|
||||
Workspace string `gorm:"primary_key"`
|
||||
DevOpsProject string `gorm:"primary_key"`
|
||||
}
|
||||
|
||||
type DevopsProject struct {
|
||||
ProjectId *string `json:"project_id,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Creator string `json:"creator"`
|
||||
CreateTime *time.Time `json:"create_time,omitempty"`
|
||||
Status *string `json:"status"`
|
||||
Visibility *string `json:"visibility,omitempty"`
|
||||
}
|
||||
@@ -24,10 +24,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
lister "k8s.io/client-go/listers/core/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
|
||||
"log"
|
||||
@@ -50,26 +49,14 @@ import (
|
||||
|
||||
"sort"
|
||||
|
||||
lister2 "k8s.io/client-go/listers/rbac/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
ksErr "kubesphere.io/kubesphere/pkg/errors"
|
||||
kserr "kubesphere.io/kubesphere/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
namespaceLister lister.NamespaceLister
|
||||
clusterRoleLister lister2.ClusterRoleLister
|
||||
)
|
||||
|
||||
func init() {
|
||||
namespaceLister = informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
clusterRoleLister = informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister()
|
||||
}
|
||||
|
||||
func UnBindDevopsProject(workspace string, devops string) error {
|
||||
db := client.NewSharedDBClient()
|
||||
db := client.DBClient()
|
||||
defer db.Close()
|
||||
return db.Delete(&WorkspaceDPBinding{Workspace: workspace, DevOpsProject: devops}).Error
|
||||
return db.Delete(&models.WorkspaceDPBinding{Workspace: workspace, DevOpsProject: devops}).Error
|
||||
}
|
||||
|
||||
func DeleteDevopsProject(username string, devops string) error {
|
||||
@@ -87,12 +74,12 @@ func DeleteDevopsProject(username string, devops string) error {
|
||||
return err
|
||||
}
|
||||
if result.StatusCode > 200 {
|
||||
return ksErr.Wrap(data)
|
||||
return kserr.Parse(data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateDevopsProject(username string, workspace string, devops DevopsProject) (*DevopsProject, error) {
|
||||
func CreateDevopsProject(username string, workspace string, devops models.DevopsProject) (*models.DevopsProject, error) {
|
||||
|
||||
data, err := json.Marshal(devops)
|
||||
|
||||
@@ -117,10 +104,10 @@ func CreateDevopsProject(username string, workspace string, devops DevopsProject
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return nil, ksErr.Wrap(data)
|
||||
return nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
var project DevopsProject
|
||||
var project models.DevopsProject
|
||||
|
||||
err = json.Unmarshal(data, &project)
|
||||
|
||||
@@ -140,7 +127,7 @@ func CreateDevopsProject(username string, workspace string, devops DevopsProject
|
||||
return &project, nil
|
||||
}
|
||||
|
||||
func createDefaultDevopsRoleBinding(workspace string, project DevopsProject) error {
|
||||
func createDefaultDevopsRoleBinding(workspace string, project models.DevopsProject) error {
|
||||
admins, err := iam.GetWorkspaceUsers(workspace, constants.WorkspaceAdmin)
|
||||
|
||||
if err != nil {
|
||||
@@ -296,7 +283,7 @@ func ListNamespaceByUser(workspaceName string, username string, keyword string,
|
||||
}
|
||||
|
||||
func Namespaces(workspaceName string) ([]*core.Namespace, error) {
|
||||
|
||||
namespaceLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
namespaces, err := namespaceLister.List(labels.SelectorFromSet(labels.Set{"kubesphere.io/workspace": workspaceName}))
|
||||
|
||||
if err != nil {
|
||||
@@ -317,11 +304,9 @@ func Namespaces(workspaceName string) ([]*core.Namespace, error) {
|
||||
}
|
||||
|
||||
func BindingDevopsProject(workspace string, devops string) error {
|
||||
//db := client.NewSharedDBClient()
|
||||
//defer db.Close()
|
||||
//return db.Create(&WorkspaceDPBinding{Workspace: workspace, DevOpsProject: devops}).Error
|
||||
// TODO FIX
|
||||
return nil
|
||||
db := client.DBClient()
|
||||
defer db.Close()
|
||||
return db.Create(&models.WorkspaceDPBinding{Workspace: workspace, DevOpsProject: devops}).Error
|
||||
}
|
||||
|
||||
func DeleteNamespace(workspace string, namespaceName string) error {
|
||||
@@ -338,7 +323,7 @@ func DeleteNamespace(workspace string, namespaceName string) error {
|
||||
|
||||
}
|
||||
|
||||
func Delete(workspace *Workspace) error {
|
||||
func Delete(workspace *models.Workspace) error {
|
||||
|
||||
err := release(workspace)
|
||||
|
||||
@@ -365,13 +350,13 @@ func Delete(workspace *Workspace) error {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return ksErr.Wrap(data)
|
||||
return kserr.Parse(data)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func release(workspace *Workspace) error {
|
||||
func release(workspace *models.Workspace) error {
|
||||
for _, namespace := range workspace.Namespaces {
|
||||
err := DeleteNamespace(workspace.Name, namespace)
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
@@ -413,7 +398,7 @@ func workspaceRoleRelease(workspace string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Create(workspace *Workspace) (*Workspace, error) {
|
||||
func Create(workspace *models.Workspace) (*models.Workspace, error) {
|
||||
|
||||
data, err := json.Marshal(workspace)
|
||||
|
||||
@@ -434,10 +419,10 @@ func Create(workspace *Workspace) (*Workspace, error) {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return nil, ksErr.Wrap(data)
|
||||
return nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
var created Workspace
|
||||
var created models.Workspace
|
||||
|
||||
err = json.Unmarshal(data, &created)
|
||||
|
||||
@@ -458,7 +443,7 @@ func Create(workspace *Workspace) (*Workspace, error) {
|
||||
return &created, nil
|
||||
}
|
||||
|
||||
func Edit(workspace *Workspace) (*Workspace, error) {
|
||||
func Edit(workspace *models.Workspace) (*models.Workspace, error) {
|
||||
|
||||
data, err := json.Marshal(workspace)
|
||||
|
||||
@@ -487,10 +472,10 @@ func Edit(workspace *Workspace) (*Workspace, error) {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return nil, ksErr.Wrap(data)
|
||||
return nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
var edited Workspace
|
||||
var edited models.Workspace
|
||||
|
||||
err = json.Unmarshal(data, &edited)
|
||||
|
||||
@@ -501,7 +486,7 @@ func Edit(workspace *Workspace) (*Workspace, error) {
|
||||
return &edited, nil
|
||||
}
|
||||
|
||||
func Detail(name string) (*Workspace, error) {
|
||||
func Detail(name string) (*models.Workspace, error) {
|
||||
|
||||
result, err := http.Get(fmt.Sprintf("http://%s/apis/account.kubesphere.io/v1alpha1/groups/%s", constants.AccountAPIServer, name))
|
||||
|
||||
@@ -517,10 +502,10 @@ func Detail(name string) (*Workspace, error) {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return nil, ksErr.Wrap(data)
|
||||
return nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
var group Group
|
||||
var group models.Group
|
||||
|
||||
err = json.Unmarshal(data, &group)
|
||||
|
||||
@@ -528,7 +513,7 @@ func Detail(name string) (*Workspace, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db := client.NewSharedDBClient()
|
||||
db := client.DBClient()
|
||||
defer db.Close()
|
||||
|
||||
workspace, err := convertGroupToWorkspace(db, group)
|
||||
@@ -541,7 +526,7 @@ func Detail(name string) (*Workspace, error) {
|
||||
}
|
||||
|
||||
// List all workspaces for the current user
|
||||
func ListWorkspaceByUser(username string, keyword string) ([]*Workspace, error) {
|
||||
func ListWorkspaceByUser(username string, keyword string) ([]*models.Workspace, error) {
|
||||
clusterRoles, err := iam.GetClusterRoles(username)
|
||||
|
||||
if err != nil {
|
||||
@@ -556,7 +541,7 @@ func ListWorkspaceByUser(username string, keyword string) ([]*Workspace, error)
|
||||
|
||||
workspacesManager := v1.PolicyRule{APIGroups: []string{"kubesphere.io"}, Verbs: []string{"list", "get"}, Resources: []string{"workspaces"}}
|
||||
|
||||
var workspaces []*Workspace
|
||||
var workspaces []*models.Workspace
|
||||
if iam.RulesMatchesRequired(rules, workspacesManager) {
|
||||
workspaces, err = fetch(nil)
|
||||
} else {
|
||||
@@ -582,13 +567,13 @@ func ListWorkspaceByUser(username string, keyword string) ([]*Workspace, error)
|
||||
return workspaces, err
|
||||
}
|
||||
|
||||
func fetch(names []string) ([]*Workspace, error) {
|
||||
func fetch(names []string) ([]*models.Workspace, error) {
|
||||
|
||||
url := fmt.Sprintf("http://%s/apis/account.kubesphere.io/v1alpha1/groups", constants.AccountAPIServer)
|
||||
|
||||
if names != nil {
|
||||
if len(names) == 0 {
|
||||
return make([]*Workspace, 0), nil
|
||||
return make([]*models.Workspace, 0), nil
|
||||
} else {
|
||||
url = url + "?path=" + strings.Join(names, ",")
|
||||
}
|
||||
@@ -608,10 +593,10 @@ func fetch(names []string) ([]*Workspace, error) {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return nil, ksErr.Wrap(data)
|
||||
return nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
var groups []Group
|
||||
var groups []models.Group
|
||||
|
||||
err = json.Unmarshal(data, &groups)
|
||||
|
||||
@@ -619,11 +604,11 @@ func fetch(names []string) ([]*Workspace, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db := client.NewSharedDBClient()
|
||||
db := client.DBClient()
|
||||
|
||||
defer db.Close()
|
||||
|
||||
workspaces := make([]*Workspace, 0)
|
||||
workspaces := make([]*models.Workspace, 0)
|
||||
for _, group := range groups {
|
||||
workspace, err := convertGroupToWorkspace(db, group)
|
||||
if err != nil {
|
||||
@@ -635,21 +620,21 @@ func fetch(names []string) ([]*Workspace, error) {
|
||||
return workspaces, nil
|
||||
}
|
||||
|
||||
func ListDevopsProjectsByUser(username string, workspace string, keyword string, orderBy string, reverse bool, limit int, offset int) (int, []DevopsProject, error) {
|
||||
func ListDevopsProjectsByUser(username string, workspace string, keyword string, orderBy string, reverse bool, limit int, offset int) (int, []models.DevopsProject, error) {
|
||||
|
||||
db := client.NewSharedDBClient()
|
||||
db := client.DBClient()
|
||||
defer db.Close()
|
||||
|
||||
var workspaceDOPBindings []WorkspaceDPBinding
|
||||
var workspaceDOPBindings []models.WorkspaceDPBinding
|
||||
|
||||
if err := db.Where("workspace = ?", workspace).Find(&workspaceDOPBindings).Error; err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
devOpsProjects := make([]DevopsProject, 0)
|
||||
devOpsProjects := make([]models.DevopsProject, 0)
|
||||
|
||||
request, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s/api/v1alpha/projects", constants.DevopsAPIServer), nil)
|
||||
request.Header.Add("X-Token-Username", username)
|
||||
request.Header.Add(constants.UserNameHeader, username)
|
||||
|
||||
result, err := http.DefaultClient.Do(request)
|
||||
if err != nil {
|
||||
@@ -662,15 +647,8 @@ func ListDevopsProjectsByUser(username string, workspace string, keyword string,
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
//if result.StatusCode == 403 || result.StatusCode == 404 {
|
||||
// if err := db.Delete(&workspaceDOPBinding).Error; err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// continue
|
||||
//}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return 0, nil, ksErr.Wrap(data)
|
||||
return 0, nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &devOpsProjects)
|
||||
@@ -720,14 +698,14 @@ func ListDevopsProjectsByUser(username string, workspace string, keyword string,
|
||||
}
|
||||
|
||||
if len(devOpsProjects) < offset {
|
||||
return len(devOpsProjects), make([]DevopsProject, 0), nil
|
||||
return len(devOpsProjects), make([]models.DevopsProject, 0), nil
|
||||
} else if len(devOpsProjects) < limit+offset {
|
||||
return len(devOpsProjects), devOpsProjects[offset:], nil
|
||||
} else {
|
||||
return len(devOpsProjects), devOpsProjects[offset : limit+offset], nil
|
||||
}
|
||||
}
|
||||
func convertGroupToWorkspace(db *gorm.DB, group Group) (*Workspace, error) {
|
||||
func convertGroupToWorkspace(db *gorm.DB, group models.Group) (*models.Workspace, error) {
|
||||
namespaces, err := Namespaces(group.Name)
|
||||
|
||||
if err != nil {
|
||||
@@ -740,7 +718,7 @@ func convertGroupToWorkspace(db *gorm.DB, group Group) (*Workspace, error) {
|
||||
namespacesNames = append(namespacesNames, namespace.Name)
|
||||
}
|
||||
|
||||
var workspaceDOPBindings []WorkspaceDPBinding
|
||||
var workspaceDOPBindings []models.WorkspaceDPBinding
|
||||
|
||||
if err := db.Where("workspace = ?", group.Name).Find(&workspaceDOPBindings).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -752,7 +730,7 @@ func convertGroupToWorkspace(db *gorm.DB, group Group) (*Workspace, error) {
|
||||
devOpsProjects = append(devOpsProjects, workspaceDOPBinding.DevOpsProject)
|
||||
}
|
||||
|
||||
workspace := Workspace{Group: group}
|
||||
workspace := models.Workspace{Group: group}
|
||||
workspace.Namespaces = namespacesNames
|
||||
workspace.DevopsProjects = devOpsProjects
|
||||
return &workspace, nil
|
||||
@@ -769,7 +747,7 @@ func CreateNamespace(namespace *core.Namespace) (*core.Namespace, error) {
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func Invite(workspaceName string, users []UserInvite) error {
|
||||
func Invite(workspaceName string, users []models.UserInvite) error {
|
||||
for _, user := range users {
|
||||
if !slice.ContainsString(constants.WorkSpaceRoles, user.Role, nil) {
|
||||
return fmt.Errorf("role %s not exist", user.Role)
|
||||
@@ -848,9 +826,9 @@ func RemoveMembers(workspaceName string, users []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Roles(workspace *Workspace) ([]*v1.ClusterRole, error) {
|
||||
func Roles(workspace *models.Workspace) ([]*v1.ClusterRole, error) {
|
||||
roles := make([]*v1.ClusterRole, 0)
|
||||
|
||||
clusterRoleLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister()
|
||||
for _, name := range constants.WorkSpaceRoles {
|
||||
|
||||
clusterRole, err := clusterRoleLister.Get(fmt.Sprintf("system:%s:%s", workspace.Name, name))
|
||||
@@ -871,7 +849,7 @@ func Roles(workspace *Workspace) ([]*v1.ClusterRole, error) {
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
func GetWorkspaceMembers(workspace string, keyword string) ([]iam.User, error) {
|
||||
func GetWorkspaceMembers(workspace string, keyword string) ([]models.User, error) {
|
||||
|
||||
url := fmt.Sprintf("http://%s/apis/account.kubesphere.io/v1alpha1/workspaces/%s/members", constants.AccountAPIServer, workspace)
|
||||
|
||||
@@ -893,10 +871,10 @@ func GetWorkspaceMembers(workspace string, keyword string) ([]iam.User, error) {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return nil, ksErr.Wrap(data)
|
||||
return nil, kserr.Parse(data)
|
||||
}
|
||||
|
||||
var users []iam.User
|
||||
var users []models.User
|
||||
|
||||
err = json.Unmarshal(data, &users)
|
||||
|
||||
@@ -908,7 +886,7 @@ func GetWorkspaceMembers(workspace string, keyword string) ([]iam.User, error) {
|
||||
|
||||
}
|
||||
|
||||
func WorkspaceRoleInit(workspace *Workspace) error {
|
||||
func WorkspaceRoleInit(workspace *models.Workspace) error {
|
||||
k8sClient := client.K8sClient()
|
||||
|
||||
admin := new(v1.ClusterRole)
|
||||
@@ -1169,7 +1147,7 @@ func unbindNamespacesRole(namespaces []string, users []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnbindWorkspace(workspace *Workspace, users []string) error {
|
||||
func UnbindWorkspace(workspace *models.Workspace, users []string) error {
|
||||
|
||||
err := unbindNamespacesRole(workspace.Namespaces, users)
|
||||
|
||||
@@ -1186,7 +1164,7 @@ func UnbindWorkspace(workspace *Workspace, users []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateWorkspaceRoleBinding(workspace *Workspace, username string, role string) error {
|
||||
func CreateWorkspaceRoleBinding(workspace *models.Workspace, username string, role string) error {
|
||||
|
||||
k8sClient := client.K8sClient()
|
||||
|
||||
@@ -1242,10 +1220,10 @@ func CreateWorkspaceRoleBinding(workspace *Workspace, username string, role stri
|
||||
|
||||
func GetDevOpsProjects(workspaceName string) ([]string, error) {
|
||||
|
||||
db := client.NewSharedDBClient()
|
||||
db := client.DBClient()
|
||||
defer db.Close()
|
||||
|
||||
var workspaceDOPBindings []WorkspaceDPBinding
|
||||
var workspaceDOPBindings []models.WorkspaceDPBinding
|
||||
|
||||
if err := db.Where("workspace = ?", workspaceName).Find(&workspaceDOPBindings).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -1304,7 +1282,7 @@ func Count() (int, error) {
|
||||
}
|
||||
|
||||
if result.StatusCode > 200 {
|
||||
return 0, ksErr.Wrap(data)
|
||||
return 0, kserr.Parse(data)
|
||||
}
|
||||
var count map[string]json.Number
|
||||
|
||||
@@ -1319,13 +1297,14 @@ func Count() (int, error) {
|
||||
v, err := value.Int64()
|
||||
|
||||
if err != nil {
|
||||
return 0, ksErr.New(ksErr.Internal, err.Error())
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func GetAllProjectNums() (int, error) {
|
||||
namespaceLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
|
||||
list, err := namespaceLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -1334,11 +1313,11 @@ func GetAllProjectNums() (int, error) {
|
||||
}
|
||||
|
||||
func GetAllDevOpsProjectsNums() (int, error) {
|
||||
db := client.NewSharedDBClient()
|
||||
db := client.DBClient()
|
||||
defer db.Close()
|
||||
|
||||
var count int
|
||||
if err := db.Model(&WorkspaceDPBinding{}).Count(&count).Error; err != nil {
|
||||
if err := db.Model(&models.WorkspaceDPBinding{}).Count(&count).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
@@ -1357,7 +1336,7 @@ func GetAllAccountNums() (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
if result.StatusCode > 200 {
|
||||
return 0, ksErr.Wrap(data)
|
||||
return 0, kserr.Parse(data)
|
||||
}
|
||||
var count map[string]json.Number
|
||||
|
||||
|
||||
Reference in New Issue
Block a user