devlopment branch (#1736)
This commit is contained in:
147
pkg/models/resources/v1alpha2/application/appplications.go
Normal file
147
pkg/models/resources/v1alpha2/application/appplications.go
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
*
|
||||
* 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 application
|
||||
|
||||
import (
|
||||
"github.com/kubernetes-sigs/application/pkg/apis/app/v1beta1"
|
||||
"github.com/kubernetes-sigs/application/pkg/client/informers/externalversions"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
app = "app"
|
||||
chart = "chart"
|
||||
release = "release"
|
||||
)
|
||||
|
||||
type appSearcher struct {
|
||||
informer externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewApplicationSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &appSearcher{informer: informers}
|
||||
}
|
||||
|
||||
func (s *appSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informer.App().V1beta1().Applications().Lister().Applications(namespace).Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (s *appSearcher) match(match map[string]string, item *v1beta1.Application) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*appSearcher) fuzzy(fuzzy map[string]string, item *v1beta1.Application) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case app:
|
||||
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*appSearcher) compare(a, b *v1beta1.Application, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *appSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
apps, err := s.informer.App().V1beta1().Applications().Lister().Applications(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1beta1.Application, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = apps
|
||||
} else {
|
||||
for _, item := range apps {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
160
pkg/models/resources/v1alpha2/clusterrole/clusterroles.go
Normal file
160
pkg/models/resources/v1alpha2/clusterrole/clusterroles.go
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
|
||||
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 clusterrole
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type clusterRoleSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewClusterRoleSearcher(informer informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &clusterRoleSearcher{informer: informer}
|
||||
}
|
||||
|
||||
func (s *clusterRoleSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informer.Rbac().V1().ClusterRoles().Lister().Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*clusterRoleSearcher) match(match map[string]string, item *rbac.ClusterRole) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.OwnerKind:
|
||||
fallthrough
|
||||
case v1alpha2.OwnerName:
|
||||
kind := match[v1alpha2.OwnerKind]
|
||||
name := match[v1alpha2.OwnerName]
|
||||
if !k8sutil.IsControlledBy(item.OwnerReferences, kind, name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.UserFacing:
|
||||
if v == "true" {
|
||||
if !isUserFacingClusterRole(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*clusterRoleSearcher) fuzzy(fuzzy map[string]string, item *rbac.ClusterRole) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*clusterRoleSearcher) compare(a, b *rbac.ClusterRole, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *clusterRoleSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
clusterRoles, err := s.informer.Rbac().V1().ClusterRoles().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*rbac.ClusterRole, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// cluster role created by user from kubesphere dashboard
|
||||
func isUserFacingClusterRole(role *rbac.ClusterRole) bool {
|
||||
if role.Annotations[constants.CreatorAnnotationKey] != "" && role.Labels[constants.WorkspaceLabelKey] == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
139
pkg/models/resources/v1alpha2/configmap/configmaps.go
Normal file
139
pkg/models/resources/v1alpha2/configmap/configmaps.go
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
|
||||
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 configmap
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type configMapSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewConfigmapSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &configMapSearcher{informer: informers}
|
||||
}
|
||||
|
||||
func (s *configMapSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informer.Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*configMapSearcher) match(match map[string]string, item *v1.ConfigMap) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*configMapSearcher) fuzzy(fuzzy map[string]string, item *v1.ConfigMap) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*configMapSearcher) compare(a, b *v1.ConfigMap, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *configMapSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
configMaps, err := s.informer.Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.ConfigMap, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
160
pkg/models/resources/v1alpha2/cronjob/cronjobs.go
Normal file
160
pkg/models/resources/v1alpha2/cronjob/cronjobs.go
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
|
||||
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 cronjob
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/batch/v1beta1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type cronJobSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewCronJobSearcher(informer informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &cronJobSearcher{informer: informer}
|
||||
}
|
||||
|
||||
func (c *cronJobSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return c.informer.Batch().V1beta1().CronJobs().Lister().CronJobs(namespace).Get(name)
|
||||
}
|
||||
|
||||
func cronJobStatus(item *v1beta1.CronJob) string {
|
||||
if item.Spec.Suspend != nil && *item.Spec.Suspend {
|
||||
return v1alpha2.StatusPaused
|
||||
}
|
||||
return v1alpha2.StatusRunning
|
||||
}
|
||||
|
||||
// Exactly Match
|
||||
func (*cronJobSearcher) match(match map[string]string, item *v1beta1.CronJob) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Status:
|
||||
if cronJobStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*cronJobSearcher) fuzzy(fuzzy map[string]string, item *v1beta1.CronJob) bool {
|
||||
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (*cronJobSearcher) compare(a, b *v1beta1.CronJob, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.LastScheduleTime:
|
||||
if a.Status.LastScheduleTime == nil {
|
||||
return true
|
||||
}
|
||||
if b.Status.LastScheduleTime == nil {
|
||||
return false
|
||||
}
|
||||
return a.Status.LastScheduleTime.Before(b.Status.LastScheduleTime)
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
default:
|
||||
fallthrough
|
||||
case v1alpha2.Name:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cronJobSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
cronJobs, err := c.informer.Batch().V1beta1().CronJobs().Lister().CronJobs(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1beta1.CronJob, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = cronJobs
|
||||
} else {
|
||||
for _, item := range cronJobs {
|
||||
if c.match(conditions.Match, item) && c.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return c.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
154
pkg/models/resources/v1alpha2/daemonset/daemonsets.go
Normal file
154
pkg/models/resources/v1alpha2/daemonset/daemonsets.go
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
|
||||
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 daemonset
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type daemonSetSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewDaemonSetSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &daemonSetSearcher{informer: informers}
|
||||
}
|
||||
|
||||
func (c *daemonSetSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return c.informer.Apps().V1().DaemonSets().Lister().DaemonSets(namespace).Get(name)
|
||||
}
|
||||
|
||||
func daemonSetStatus(item *v1.DaemonSet) string {
|
||||
if item.Status.NumberAvailable == 0 {
|
||||
return v1alpha2.StatusStopped
|
||||
} else if item.Status.DesiredNumberScheduled == item.Status.NumberAvailable {
|
||||
return v1alpha2.StatusRunning
|
||||
} else {
|
||||
return v1alpha2.StatusUpdating
|
||||
}
|
||||
}
|
||||
|
||||
// Exactly Match
|
||||
func (*daemonSetSearcher) match(match map[string]string, item *v1.DaemonSet) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
if daemonSetStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*daemonSetSearcher) fuzzy(fuzzy map[string]string, item *v1.DaemonSet) bool {
|
||||
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (*daemonSetSearcher) compare(a, b *v1.DaemonSet, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (c *daemonSetSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
daemonSets, err := c.informer.Apps().V1().DaemonSets().Lister().DaemonSets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.DaemonSet, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = daemonSets
|
||||
} else {
|
||||
for _, item := range daemonSets {
|
||||
if c.match(conditions.Match, item) && c.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return c.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
153
pkg/models/resources/v1alpha2/hpa/horizontalpodautoscalers.go
Normal file
153
pkg/models/resources/v1alpha2/hpa/horizontalpodautoscalers.go
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
*
|
||||
* 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 hpa
|
||||
|
||||
import (
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type hpaSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewHpaSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &hpaSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *hpaSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Autoscaling().V2beta2().HorizontalPodAutoscalers().Lister().HorizontalPodAutoscalers(namespace).Get(name)
|
||||
}
|
||||
|
||||
func hpaTargetMatch(item *autoscalingv2beta2.HorizontalPodAutoscaler, kind, name string) bool {
|
||||
return item.Spec.ScaleTargetRef.Kind == kind && item.Spec.ScaleTargetRef.Name == name
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*hpaSearcher) match(match map[string]string, item *autoscalingv2beta2.HorizontalPodAutoscaler) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.TargetKind:
|
||||
fallthrough
|
||||
case v1alpha2.TargetName:
|
||||
kind := match[v1alpha2.TargetKind]
|
||||
name := match[v1alpha2.TargetName]
|
||||
if !hpaTargetMatch(item, kind, name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if item.Labels[k] != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*hpaSearcher) fuzzy(fuzzy map[string]string, item *autoscalingv2beta2.HorizontalPodAutoscaler) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) && !v1alpha2.SearchFuzzy(item.Annotations, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*hpaSearcher) compare(a, b *autoscalingv2beta2.HorizontalPodAutoscaler, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *hpaSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
|
||||
horizontalPodAutoscalers, err := s.informers.Autoscaling().V2beta2().HorizontalPodAutoscalers().Lister().HorizontalPodAutoscalers(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*autoscalingv2beta2.HorizontalPodAutoscaler, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = horizontalPodAutoscalers
|
||||
} else {
|
||||
for _, item := range horizontalPodAutoscalers {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
142
pkg/models/resources/v1alpha2/ingress/ingresses.go
Normal file
142
pkg/models/resources/v1alpha2/ingress/ingresses.go
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
|
||||
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 ingress
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type ingressSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewIngressSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &ingressSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *ingressSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Extensions().V1beta1().Ingresses().Lister().Ingresses(namespace).Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*ingressSearcher) match(match map[string]string, item *v1beta1.Ingress) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*ingressSearcher) fuzzy(fuzzy map[string]string, item *v1beta1.Ingress) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*ingressSearcher) compare(a, b *v1beta1.Ingress, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ingressSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
ingresses, err := s.informers.Extensions().V1beta1().Ingresses().Lister().Ingresses(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1beta1.Ingress, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
80
pkg/models/resources/v1alpha2/interface.go
Normal file
80
pkg/models/resources/v1alpha2/interface.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
App = "app"
|
||||
Chart = "chart"
|
||||
Release = "release"
|
||||
Name = "name"
|
||||
Label = "label"
|
||||
OwnerKind = "ownerKind"
|
||||
OwnerName = "ownerName"
|
||||
TargetKind = "targetKind"
|
||||
TargetName = "targetName"
|
||||
Role = "role"
|
||||
CreateTime = "createTime"
|
||||
UpdateTime = "updateTime"
|
||||
StartTime = "startTime"
|
||||
LastScheduleTime = "lastScheduleTime"
|
||||
Annotation = "Annotation"
|
||||
Keyword = "keyword"
|
||||
UserFacing = "userfacing"
|
||||
Status = "status"
|
||||
|
||||
StatusRunning = "running"
|
||||
StatusPaused = "paused"
|
||||
StatusPending = "pending"
|
||||
StatusUpdating = "updating"
|
||||
StatusStopped = "stopped"
|
||||
StatusFailed = "failed"
|
||||
StatusBound = "bound"
|
||||
StatusLost = "lost"
|
||||
StatusComplete = "complete"
|
||||
StatusWarning = "warning"
|
||||
StatusUnschedulable = "unschedulable"
|
||||
Deployments = "deployments"
|
||||
DaemonSets = "daemonsets"
|
||||
Roles = "roles"
|
||||
Workspaces = "workspaces"
|
||||
WorkspaceRoles = "workspaceroles"
|
||||
CronJobs = "cronjobs"
|
||||
ConfigMaps = "configmaps"
|
||||
Ingresses = "ingresses"
|
||||
Jobs = "jobs"
|
||||
PersistentVolumeClaims = "persistentvolumeclaims"
|
||||
Pods = "pods"
|
||||
Secrets = "secrets"
|
||||
Services = "services"
|
||||
StatefulSets = "statefulsets"
|
||||
HorizontalPodAutoscalers = "horizontalpodautoscalers"
|
||||
Applications = "applications"
|
||||
Nodes = "nodes"
|
||||
Namespaces = "namespaces"
|
||||
StorageClasses = "storageclasses"
|
||||
ClusterRoles = "clusterroles"
|
||||
S2iBuilderTemplates = "s2ibuildertemplates"
|
||||
S2iBuilders = "s2ibuilders"
|
||||
S2iRuns = "s2iruns"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Get(namespace, name string) (interface{}, error)
|
||||
Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error)
|
||||
}
|
||||
|
||||
func SearchFuzzy(m map[string]string, key, value string) bool {
|
||||
|
||||
val, exist := m[key]
|
||||
|
||||
if value == "" && (!exist || val == "") {
|
||||
return true
|
||||
} else if value != "" && strings.Contains(val, value) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
191
pkg/models/resources/v1alpha2/job/jobs.go
Normal file
191
pkg/models/resources/v1alpha2/job/jobs.go
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
|
||||
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 job
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
const (
|
||||
includeCronJob = "includeCronJob"
|
||||
cronJobKind = "CronJob"
|
||||
s2iRunKind = "S2iRun"
|
||||
includeS2iRun = "includeS2iRun"
|
||||
)
|
||||
|
||||
type jobSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewJobSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &jobSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *jobSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Batch().V1().Jobs().Lister().Jobs(namespace).Get(name)
|
||||
}
|
||||
|
||||
func jobStatus(item *batchv1.Job) string {
|
||||
status := v1alpha2.StatusFailed
|
||||
if item.Status.Active > 0 {
|
||||
status = v1alpha2.StatusRunning
|
||||
} else if item.Status.Failed > 0 {
|
||||
status = v1alpha2.StatusFailed
|
||||
} else if item.Status.Succeeded > 0 {
|
||||
status = v1alpha2.StatusComplete
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
||||
// Exactly Match
|
||||
func (*jobSearcher) match(match map[string]string, item *batchv1.Job) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
if jobStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
case includeCronJob:
|
||||
if v == "false" && k8sutil.IsControlledBy(item.OwnerReferences, cronJobKind, "") {
|
||||
return false
|
||||
}
|
||||
case includeS2iRun:
|
||||
if v == "false" && k8sutil.IsControlledBy(item.OwnerReferences, s2iRunKind, "") {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*jobSearcher) fuzzy(fuzzy map[string]string, item *batchv1.Job) bool {
|
||||
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func jobUpdateTime(item *batchv1.Job) time.Time {
|
||||
updateTime := item.CreationTimestamp.Time
|
||||
for _, condition := range item.Status.Conditions {
|
||||
if updateTime.Before(condition.LastProbeTime.Time) {
|
||||
updateTime = condition.LastProbeTime.Time
|
||||
}
|
||||
if updateTime.Before(condition.LastTransitionTime.Time) {
|
||||
updateTime = condition.LastTransitionTime.Time
|
||||
}
|
||||
}
|
||||
return updateTime
|
||||
}
|
||||
|
||||
func (*jobSearcher) compare(a, b *batchv1.Job, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.UpdateTime:
|
||||
return jobUpdateTime(a).Before(jobUpdateTime(b))
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *jobSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
jobs, err := s.informers.Batch().V1().Jobs().Lister().Jobs(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*batchv1.Job, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
138
pkg/models/resources/v1alpha2/namespace/namespaces.go
Normal file
138
pkg/models/resources/v1alpha2/namespace/namespaces.go
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
|
||||
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 namespace
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type namespaceSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNamespaceSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &namespaceSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *namespaceSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Namespaces().Lister().Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*namespaceSearcher) match(match map[string]string, item *v1.Namespace) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*namespaceSearcher) fuzzy(fuzzy map[string]string, item *v1.Namespace) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*namespaceSearcher) compare(a, b *v1.Namespace, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *namespaceSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
namespaces, err := s.informers.Core().V1().Namespaces().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Namespace, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
184
pkg/models/resources/v1alpha2/node/nodes.go
Normal file
184
pkg/models/resources/v1alpha2/node/nodes.go
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
|
||||
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 node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
const (
|
||||
nodeConfigOK v1.NodeConditionType = "ConfigOK"
|
||||
nodeKubeletReady v1.NodeConditionType = "KubeletReady"
|
||||
)
|
||||
|
||||
type nodeSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNodeSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &nodeSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *nodeSearcher) Get(_, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Nodes().Lister().Get(name)
|
||||
}
|
||||
|
||||
func getNodeStatus(node *v1.Node) string {
|
||||
if node.Spec.Unschedulable {
|
||||
return v1alpha2.StatusUnschedulable
|
||||
}
|
||||
for _, condition := range node.Status.Conditions {
|
||||
if isUnhealthyStatus(condition) {
|
||||
return v1alpha2.StatusWarning
|
||||
}
|
||||
}
|
||||
|
||||
return v1alpha2.StatusRunning
|
||||
}
|
||||
|
||||
var expectedConditions = map[v1.NodeConditionType]v1.ConditionStatus{
|
||||
v1.NodeMemoryPressure: v1.ConditionFalse,
|
||||
v1.NodeDiskPressure: v1.ConditionFalse,
|
||||
v1.NodePIDPressure: v1.ConditionFalse,
|
||||
v1.NodeNetworkUnavailable: v1.ConditionFalse,
|
||||
nodeConfigOK: v1.ConditionTrue,
|
||||
nodeKubeletReady: v1.ConditionTrue,
|
||||
v1.NodeReady: v1.ConditionTrue,
|
||||
}
|
||||
|
||||
func isUnhealthyStatus(condition v1.NodeCondition) bool {
|
||||
expectedStatus := expectedConditions[condition.Type]
|
||||
if expectedStatus != "" && condition.Status != expectedStatus {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*nodeSearcher) match(match map[string]string, item *v1.Node) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Role:
|
||||
labelKey := fmt.Sprintf("node-role.kubernetes.io/%s", v)
|
||||
if _, ok := item.Labels[labelKey]; !ok {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Status:
|
||||
if getNodeStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*nodeSearcher) fuzzy(fuzzy map[string]string, item *v1.Node) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*nodeSearcher) compare(a, b *v1.Node, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *nodeSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
nodes, err := s.informers.Core().V1().Nodes().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Node, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
|
||||
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 persistentvolumeclaim
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"strconv"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
const (
|
||||
storageClassName = "storageClassName"
|
||||
)
|
||||
|
||||
type persistentVolumeClaimSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewPersistentVolumeClaimSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &persistentVolumeClaimSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *persistentVolumeClaimSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().PersistentVolumeClaims().Lister().PersistentVolumeClaims(namespace).Get(name)
|
||||
}
|
||||
|
||||
func pvcStatus(item *v1.PersistentVolumeClaim) string {
|
||||
status := v1alpha2.StatusPending
|
||||
if item.Status.Phase == v1.ClaimPending {
|
||||
status = v1alpha2.StatusPending
|
||||
} else if item.Status.Phase == v1.ClaimBound {
|
||||
status = v1alpha2.StatusBound
|
||||
} else if item.Status.Phase == v1.ClaimLost {
|
||||
status = v1alpha2.StatusLost
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*persistentVolumeClaimSearcher) match(match map[string]string, item *v1.PersistentVolumeClaim) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Status:
|
||||
statuses := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(statuses, pvcStatus(item)) {
|
||||
return false
|
||||
}
|
||||
case storageClassName:
|
||||
if item.Spec.StorageClassName == nil || *item.Spec.StorageClassName != v {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*persistentVolumeClaimSearcher) fuzzy(fuzzy map[string]string, item *v1.PersistentVolumeClaim) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*persistentVolumeClaimSearcher) compare(a, b *v1.PersistentVolumeClaim, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *persistentVolumeClaimSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
persistentVolumeClaims, err := s.informers.Core().V1().PersistentVolumeClaims().Lister().PersistentVolumeClaims(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.PersistentVolumeClaim, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
inUse := s.countPods(i.Name, i.Namespace)
|
||||
if i.Annotations == nil {
|
||||
i.Annotations = make(map[string]string)
|
||||
}
|
||||
i.Annotations["kubesphere.io/in-use"] = strconv.FormatBool(inUse)
|
||||
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (s *persistentVolumeClaimSearcher) countPods(name, namespace string) bool {
|
||||
pods, err := s.informers.Core().V1().Pods().Lister().Pods(namespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, pod := range pods {
|
||||
for _, pvc := range pod.Spec.Volumes {
|
||||
if pvc.PersistentVolumeClaim != nil && pvc.PersistentVolumeClaim.ClaimName == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
281
pkg/models/resources/v1alpha2/pod/pods.go
Normal file
281
pkg/models/resources/v1alpha2/pod/pods.go
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
|
||||
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 pod
|
||||
|
||||
import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type podSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewPodSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &podSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *podSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Pods().Lister().Pods(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (s *podSearcher) podBelongTo(item *v1.Pod, kind string, name string) bool {
|
||||
switch kind {
|
||||
case "Deployment":
|
||||
if s.podBelongToDeployment(item, name) {
|
||||
return true
|
||||
}
|
||||
case "ReplicaSet":
|
||||
if podBelongToReplicaSet(item, name) {
|
||||
return true
|
||||
}
|
||||
case "DaemonSet":
|
||||
if podBelongToDaemonSet(item, name) {
|
||||
return true
|
||||
}
|
||||
case "StatefulSet":
|
||||
if podBelongToStatefulSet(item, name) {
|
||||
return true
|
||||
}
|
||||
case "Job":
|
||||
if podBelongToJob(item, name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func replicaSetBelongToDeployment(replicaSet *appsv1.ReplicaSet, deploymentName string) bool {
|
||||
for _, owner := range replicaSet.OwnerReferences {
|
||||
if owner.Kind == "Deployment" && owner.Name == deploymentName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func podBelongToDaemonSet(item *v1.Pod, name string) bool {
|
||||
for _, owner := range item.OwnerReferences {
|
||||
if owner.Kind == "DaemonSet" && owner.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func podBelongToJob(item *v1.Pod, name string) bool {
|
||||
for _, owner := range item.OwnerReferences {
|
||||
if owner.Kind == "Job" && owner.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func podBelongToReplicaSet(item *v1.Pod, replicaSetName string) bool {
|
||||
for _, owner := range item.OwnerReferences {
|
||||
if owner.Kind == "ReplicaSet" && owner.Name == replicaSetName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func podBelongToStatefulSet(item *v1.Pod, statefulSetName string) bool {
|
||||
for _, owner := range item.OwnerReferences {
|
||||
if owner.Kind == "StatefulSet" && owner.Name == statefulSetName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *podSearcher) podBelongToDeployment(item *v1.Pod, deploymentName string) bool {
|
||||
replicas, err := s.informers.Apps().V1().ReplicaSets().Lister().ReplicaSets(item.Namespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, r := range replicas {
|
||||
if replicaSetBelongToDeployment(r, deploymentName) && podBelongToReplicaSet(item, r.Name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func podBindPVC(item *v1.Pod, pvcName string) bool {
|
||||
for _, v := range item.Spec.Volumes {
|
||||
if v.VolumeSource.PersistentVolumeClaim != nil &&
|
||||
v.VolumeSource.PersistentVolumeClaim.ClaimName == pvcName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *podSearcher) podBelongToService(item *v1.Pod, serviceName string) bool {
|
||||
service, err := s.informers.Core().V1().Services().Lister().Services(item.Namespace).Get(serviceName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
|
||||
if selector.Empty() || !selector.Matches(labels.Set(item.Labels)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (s *podSearcher) match(match map[string]string, item *v1.Pod) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.OwnerKind:
|
||||
fallthrough
|
||||
case v1alpha2.OwnerName:
|
||||
kind := match[v1alpha2.OwnerKind]
|
||||
name := match[v1alpha2.OwnerName]
|
||||
if !s.podBelongTo(item, kind, name) {
|
||||
return false
|
||||
}
|
||||
case "nodeName":
|
||||
if item.Spec.NodeName != v {
|
||||
return false
|
||||
}
|
||||
case "pvcName":
|
||||
if !podBindPVC(item, v) {
|
||||
return false
|
||||
}
|
||||
case "serviceName":
|
||||
if !s.podBelongToService(item, v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*podSearcher) fuzzy(fuzzy map[string]string, item *v1.Pod) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*podSearcher) compare(a, b *v1.Pod, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.StartTime:
|
||||
if a.Status.StartTime == nil {
|
||||
return false
|
||||
}
|
||||
if b.Status.StartTime == nil {
|
||||
return true
|
||||
}
|
||||
return a.Status.StartTime.Before(b.Status.StartTime)
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *podSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
|
||||
pods, err := s.informers.Core().V1().Pods().Lister().Pods(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Pod, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
137
pkg/models/resources/v1alpha2/resource/resources.go
Normal file
137
pkg/models/resources/v1alpha2/resource/resources.go
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
|
||||
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 resource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/application"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/clusterrole"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/configmap"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/cronjob"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/daemonset"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/hpa"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/ingress"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/job"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/namespace"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/node"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/persistentvolumeclaim"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/pod"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/role"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/s2buildertemplate"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/s2ibuilder"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/s2irun"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/secret"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/service"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/statefulset"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/storageclass"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/workspace"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
)
|
||||
|
||||
type ResourceGetter struct {
|
||||
resourcesGetters map[string]v1alpha2.Interface
|
||||
}
|
||||
|
||||
func NewResourceGetter(factory informers.InformerFactory) *ResourceGetter {
|
||||
resourceGetters := make(map[string]v1alpha2.Interface)
|
||||
|
||||
resourceGetters[v1alpha2.ConfigMaps] = configmap.NewConfigmapSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.CronJobs] = cronjob.NewCronJobSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.DaemonSets] = daemonset.NewDaemonSetSearcher(factory.KubernetesSharedInformerFactory())
|
||||
// resourceGetters[Deployments] =
|
||||
resourceGetters[v1alpha2.Ingresses] = ingress.NewIngressSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Jobs] = job.NewJobSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.PersistentVolumeClaims] = persistentvolumeclaim.NewPersistentVolumeClaimSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Secrets] = secret.NewSecretSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Services] = service.NewServiceSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.StatefulSets] = statefulset.NewStatefulSetSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Pods] = pod.NewPodSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Roles] = role.NewRoleSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Nodes] = node.NewNodeSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Namespaces] = namespace.NewNamespaceSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.ClusterRoles] = clusterrole.NewClusterRoleSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.StorageClasses] = storageclass.NewStorageClassesSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.HorizontalPodAutoscalers] = hpa.NewHpaSearcher(factory.KubernetesSharedInformerFactory())
|
||||
|
||||
resourceGetters[v1alpha2.S2iBuilders] = s2ibuilder.NewS2iBuilderSearcher(factory.S2iSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.S2iRuns] = s2irun.NewS2iRunSearcher(factory.S2iSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.S2iBuilderTemplates] = s2buildertemplate.NewS2iBuidlerTemplateSearcher(factory.S2iSharedInformerFactory())
|
||||
|
||||
resourceGetters[v1alpha2.Workspaces] = workspace.NewWorkspaceSearcher(factory.KubeSphereSharedInformerFactory())
|
||||
|
||||
resourceGetters[v1alpha2.Applications] = application.NewApplicationSearcher(factory.ApplicationSharedInformerFactory())
|
||||
|
||||
return &ResourceGetter{resourcesGetters: resourceGetters}
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
//injector = v1alpha2.extraAnnotationInjector{}
|
||||
clusterResources = []string{v1alpha2.Nodes, v1alpha2.Workspaces, v1alpha2.Namespaces, v1alpha2.ClusterRoles, v1alpha2.StorageClasses, v1alpha2.S2iBuilderTemplates}
|
||||
)
|
||||
|
||||
func (r *ResourceGetter) GetResource(namespace, resource, name string) (interface{}, error) {
|
||||
if searcher, ok := r.resourcesGetters[resource]; ok {
|
||||
resource, err := searcher.Get(namespace, name)
|
||||
if err != nil {
|
||||
klog.Errorf("resource %s.%s.%s not found: %s", namespace, resource, name, err)
|
||||
return nil, err
|
||||
}
|
||||
return resource, nil
|
||||
}
|
||||
return nil, fmt.Errorf("resource %s.%s.%s not found", namespace, resource, name)
|
||||
}
|
||||
|
||||
func (r *ResourceGetter) ListResources(namespace, resource string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
|
||||
items := make([]interface{}, 0)
|
||||
var err error
|
||||
var result []interface{}
|
||||
|
||||
// none namespace resource
|
||||
if namespace != "" && sliceutil.HasString(clusterResources, resource) {
|
||||
err = fmt.Errorf("namespaced resource %s not found", resource)
|
||||
klog.Errorln(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if searcher, ok := r.resourcesGetters[resource]; ok {
|
||||
result, err = searcher.Search(namespace, conditions, orderBy, reverse)
|
||||
} else {
|
||||
err = fmt.Errorf("namespaced resource %s not found", resource)
|
||||
klog.Errorln(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
klog.Errorln(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if limit == -1 || limit+offset > len(result) {
|
||||
limit = len(result) - offset
|
||||
}
|
||||
|
||||
result = result[offset : offset+limit]
|
||||
|
||||
return &models.PageableResponse{TotalCount: len(result), Items: items}, nil
|
||||
}
|
||||
152
pkg/models/resources/v1alpha2/role/roles.go
Normal file
152
pkg/models/resources/v1alpha2/role/roles.go
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
|
||||
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 role
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type roleSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewRoleSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &roleSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *roleSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Rbac().V1().Roles().Lister().Roles(namespace).Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*roleSearcher) match(match map[string]string, item *rbac.Role) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.UserFacing:
|
||||
if v == "true" {
|
||||
if !isUserFacingRole(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*roleSearcher) fuzzy(fuzzy map[string]string, item *rbac.Role) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*roleSearcher) compare(a, b *rbac.Role, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *roleSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
roles, err := s.informers.Rbac().V1().Roles().Lister().Roles(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*rbac.Role, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// role created by user from kubesphere dashboard
|
||||
func isUserFacingRole(role *rbac.Role) bool {
|
||||
if role.Annotations[constants.CreatorAnnotationKey] != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
|
||||
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 s2buildertemplate
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/s2ioperator/pkg/apis/devops/v1alpha1"
|
||||
"github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type s2iBuilderTemplateSearcher struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewS2iBuidlerTemplateSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &s2iBuilderTemplateSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *s2iBuilderTemplateSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Devops().V1alpha1().S2iBuilderTemplates().Lister().Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*s2iBuilderTemplateSearcher) match(match map[string]string, item *v1alpha1.S2iBuilderTemplate) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*s2iBuilderTemplateSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iBuilderTemplate) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*s2iBuilderTemplateSearcher) compare(a, b *v1alpha1.S2iBuilderTemplate, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *s2iBuilderTemplateSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
builderTemplates, err := s.informers.Devops().V1alpha1().S2iBuilderTemplates().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1alpha1.S2iBuilderTemplate, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = builderTemplates
|
||||
} else {
|
||||
for _, item := range builderTemplates {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
138
pkg/models/resources/v1alpha2/s2ibuilder/s2ibuilder.go
Normal file
138
pkg/models/resources/v1alpha2/s2ibuilder/s2ibuilder.go
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
|
||||
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 s2ibuilder
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/s2ioperator/pkg/apis/devops/v1alpha1"
|
||||
"github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type s2iBuilderSearcher struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewS2iBuilderSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &s2iBuilderSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *s2iBuilderSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Devops().V1alpha1().S2iBuilders().Lister().S2iBuilders(namespace).Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*s2iBuilderSearcher) match(match map[string]string, item *v1alpha1.S2iBuilder) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*s2iBuilderSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iBuilder) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*s2iBuilderSearcher) compare(a, b *v1alpha1.S2iBuilder, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *s2iBuilderSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
s2iBuilders, err := s.informers.Devops().V1alpha1().S2iBuilders().Lister().S2iBuilders(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1alpha1.S2iBuilder, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = s2iBuilders
|
||||
} else {
|
||||
for _, item := range s2iBuilders {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
145
pkg/models/resources/v1alpha2/s2irun/s2irun.go
Normal file
145
pkg/models/resources/v1alpha2/s2irun/s2irun.go
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
|
||||
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 s2irun
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"github.com/kubesphere/s2ioperator/pkg/apis/devops/v1alpha1"
|
||||
)
|
||||
|
||||
type s2iRunSearcher struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewS2iRunSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &s2iRunSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *s2iRunSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Devops().V1alpha1().S2iRuns().Lister().S2iRuns(namespace).Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*s2iRunSearcher) match(match map[string]string, item *v1alpha1.S2iRun) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Status:
|
||||
if string(item.Status.RunState) != v {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*s2iRunSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iRun) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*s2iRunSearcher) compare(a, b *v1alpha1.S2iRun, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *s2iRunSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
s2iRuns, err := s.informers.Devops().V1alpha1().S2iRuns().Lister().S2iRuns(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1alpha1.S2iRun, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = s2iRuns
|
||||
} else {
|
||||
for _, item := range s2iRuns {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
146
pkg/models/resources/v1alpha2/secret/secrets.go
Normal file
146
pkg/models/resources/v1alpha2/secret/secrets.go
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
|
||||
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 secret
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type secretSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewSecretSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &secretSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *secretSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Secrets().Lister().Secrets(namespace).Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*secretSearcher) match(match map[string]string, item *v1.Secret) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case "type":
|
||||
if string(item.Type) != v {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*secretSearcher) fuzzy(fuzzy map[string]string, item *v1.Secret) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*secretSearcher) compare(a, b *v1.Secret, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *secretSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
secrets, err := s.informers.Core().V1().Secrets().Lister().Secrets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Secret, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
142
pkg/models/resources/v1alpha2/service/services.go
Normal file
142
pkg/models/resources/v1alpha2/service/services.go
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
|
||||
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 service
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type serviceSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewServiceSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &serviceSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *serviceSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Services().Lister().Services(namespace).Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*serviceSearcher) match(match map[string]string, item *v1.Service) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*serviceSearcher) fuzzy(fuzzy map[string]string, item *v1.Service) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*serviceSearcher) compare(a, b *v1.Service, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *serviceSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
services, err := s.informers.Core().V1().Services().Lister().Services(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Service, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
160
pkg/models/resources/v1alpha2/statefulset/statefulsets.go
Normal file
160
pkg/models/resources/v1alpha2/statefulset/statefulsets.go
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
|
||||
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 statefulset
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type statefulSetSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewStatefulSetSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &statefulSetSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *statefulSetSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Apps().V1().StatefulSets().Lister().StatefulSets(namespace).Get(name)
|
||||
}
|
||||
|
||||
func statefulSetStatus(item *v1.StatefulSet) string {
|
||||
if item.Spec.Replicas != nil {
|
||||
if item.Status.ReadyReplicas == 0 && *item.Spec.Replicas == 0 {
|
||||
return v1alpha2.StatusStopped
|
||||
} else if item.Status.ReadyReplicas == *item.Spec.Replicas {
|
||||
return v1alpha2.StatusRunning
|
||||
} else {
|
||||
return v1alpha2.StatusUpdating
|
||||
}
|
||||
}
|
||||
return v1alpha2.StatusStopped
|
||||
}
|
||||
|
||||
// Exactly Match
|
||||
func (*statefulSetSearcher) match(match map[string]string, item *v1.StatefulSet) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Status:
|
||||
if statefulSetStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*statefulSetSearcher) fuzzy(fuzzy map[string]string, item *v1.StatefulSet) bool {
|
||||
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case v1alpha2.App:
|
||||
if !strings.Contains(item.Labels[v1alpha2.Chart], v) && !strings.Contains(item.Labels[v1alpha2.Release], v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (*statefulSetSearcher) compare(a, b *v1.StatefulSet, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *statefulSetSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
statefulSets, err := s.informers.Apps().V1().StatefulSets().Lister().StatefulSets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.StatefulSet, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
158
pkg/models/resources/v1alpha2/storageclass/storageclasses.go
Normal file
158
pkg/models/resources/v1alpha2/storageclass/storageclasses.go
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
|
||||
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 storageclass
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type storageClassesSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewStorageClassesSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &storageClassesSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *storageClassesSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Storage().V1().StorageClasses().Lister().Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*storageClassesSearcher) match(match map[string]string, item *v1.StorageClass) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*storageClassesSearcher) fuzzy(fuzzy map[string]string, item *v1.StorageClass) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*storageClassesSearcher) compare(a, b *v1.StorageClass, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *storageClassesSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
storageClasses, err := s.informers.Storage().V1().StorageClasses().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.StorageClass, 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) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
count := s.countPersistentVolumeClaims(i.Name)
|
||||
if i.Annotations == nil {
|
||||
i.Annotations = make(map[string]string)
|
||||
i.Annotations["kubesphere.io/pvc-count"] = string(count)
|
||||
}
|
||||
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (s *storageClassesSearcher) countPersistentVolumeClaims(name string) int {
|
||||
pvcs, err := s.informers.Core().V1().PersistentVolumeClaims().Lister().List(labels.Everything())
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
var count int
|
||||
|
||||
for _, pvc := range pvcs {
|
||||
if *pvc.Spec.StorageClassName == name || (pvc.Annotations != nil && pvc.Annotations[corev1.BetaStorageClassAnnotation] == name) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
139
pkg/models/resources/v1alpha2/workspace/workspaces.go
Normal file
139
pkg/models/resources/v1alpha2/workspace/workspaces.go
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
|
||||
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 workspace
|
||||
|
||||
import (
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type workspaceSearcher struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewWorkspaceSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &workspaceSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *workspaceSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Tenant().V1alpha1().Workspaces().Lister().Get(name)
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*workspaceSearcher) match(match map[string]string, item *tenantv1alpha1.Workspace) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
names := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Keyword:
|
||||
if !strings.Contains(item.Name, v) && !v1alpha2.SearchFuzzy(item.Labels, "", v) && !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[k]; !ok || val != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Fuzzy searchInNamespace
|
||||
func (*workspaceSearcher) fuzzy(fuzzy map[string]string, item *tenantv1alpha1.Workspace) bool {
|
||||
for k, v := range fuzzy {
|
||||
switch k {
|
||||
case v1alpha2.Name:
|
||||
if !strings.Contains(item.Name, v) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Label:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, "", v) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Annotation:
|
||||
if !v1alpha2.SearchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !v1alpha2.SearchFuzzy(item.Labels, k, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*workspaceSearcher) compare(a, b *tenantv1alpha1.Workspace, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.CreateTime:
|
||||
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
|
||||
case v1alpha2.Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *workspaceSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
|
||||
workspaces, err := s.informers.Tenant().V1alpha1().Workspaces().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*tenantv1alpha1.Workspace, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = workspaces
|
||||
} else {
|
||||
for _, item := range workspaces {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
tmp := i
|
||||
i = j
|
||||
j = tmp
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
Reference in New Issue
Block a user