devlopment branch (#1736)

This commit is contained in:
zryfish
2020-01-02 20:52:00 +08:00
committed by GitHub
parent ff0ffe8650
commit eceadec69c
440 changed files with 61524 additions and 3699 deletions

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View File

@@ -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
}

View 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
}

View 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
}

View 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
}

View 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 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}