refine tenant api

Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2019-04-01 02:59:19 +08:00
parent 744bd053e3
commit 93ad572e19
202 changed files with 13517 additions and 7951 deletions

View File

@@ -20,6 +20,7 @@ package resources
import (
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"sort"
"strings"
@@ -30,16 +31,34 @@ import (
type clusterRoleSearcher struct {
}
func (*clusterRoleSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().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 ownerKind:
fallthrough
case ownerName:
kind := match[ownerKind]
name := match[ownerName]
if !k8sutil.IsControlledBy(item.OwnerReferences, kind, name) {
return false
}
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -62,10 +81,6 @@ func (*clusterRoleSearcher) fuzzy(fuzzy map[string]string, item *rbac.ClusterRol
return false
}
return false
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -77,7 +92,7 @@ func (*clusterRoleSearcher) fuzzy(fuzzy map[string]string, item *rbac.ClusterRol
func (*clusterRoleSearcher) compare(a, b *rbac.ClusterRole, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough
@@ -86,7 +101,7 @@ func (*clusterRoleSearcher) compare(a, b *rbac.ClusterRole, orderBy string) bool
}
}
func (s *clusterRoleSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
func (s *clusterRoleSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
clusterRoles, err := informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister().List(labels.Everything())
if err != nil {

View File

@@ -30,6 +30,10 @@ import (
type configMapSearcher struct {
}
func (*configMapSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().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 {
@@ -38,8 +42,14 @@ func (*configMapSearcher) match(match map[string]string, item *v1.ConfigMap) boo
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -66,10 +76,6 @@ func (*configMapSearcher) fuzzy(fuzzy map[string]string, item *v1.ConfigMap) boo
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -81,7 +87,7 @@ func (*configMapSearcher) fuzzy(fuzzy map[string]string, item *v1.ConfigMap) boo
func (*configMapSearcher) compare(a, b *v1.ConfigMap, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -31,6 +31,10 @@ import (
type cronJobSearcher struct {
}
func (*cronJobSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Batch().V1beta1().CronJobs().Lister().CronJobs(namespace).Get(name)
}
func cronJobStatus(item *v1beta1.CronJob) string {
if item.Spec.Suspend != nil && *item.Spec.Suspend {
return paused
@@ -42,12 +46,22 @@ func cronJobStatus(item *v1beta1.CronJob) string {
func (*cronJobSearcher) match(match map[string]string, item *v1beta1.CronJob) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
case status:
if cronJobStatus(item) != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -74,10 +88,6 @@ func (*cronJobSearcher) fuzzy(fuzzy map[string]string, item *v1beta1.CronJob) bo
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -98,7 +108,7 @@ func (*cronJobSearcher) compare(a, b *v1beta1.CronJob, orderBy string) bool {
return false
}
return a.Status.LastScheduleTime.Before(b.Status.LastScheduleTime)
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
default:
fallthrough

View File

@@ -30,6 +30,10 @@ import (
type daemonSetSearcher struct {
}
func (*daemonSetSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Apps().V1().DaemonSets().Lister().DaemonSets(namespace).Get(name)
}
func daemonSetStatus(item *v1.DaemonSet) string {
if item.Status.NumberAvailable == 0 {
return stopped
@@ -48,8 +52,18 @@ func (*daemonSetSearcher) match(match map[string]string, item *v1.DaemonSet) boo
if daemonSetStatus(item) != v {
return false
}
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -76,10 +90,6 @@ func (*daemonSetSearcher) fuzzy(fuzzy map[string]string, item *v1.DaemonSet) boo
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -92,7 +102,7 @@ func (*daemonSetSearcher) fuzzy(fuzzy map[string]string, item *v1.DaemonSet) boo
func (*daemonSetSearcher) compare(a, b *v1.DaemonSet, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -31,6 +31,10 @@ import (
type deploymentSearcher struct {
}
func (*deploymentSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Apps().V1().Deployments().Lister().Deployments(namespace).Get(name)
}
func deploymentStatus(item *v1.Deployment) string {
if item.Spec.Replicas != nil {
if item.Status.ReadyReplicas == 0 && *item.Spec.Replicas == 0 {
@@ -52,8 +56,18 @@ func (*deploymentSearcher) match(match map[string]string, item *v1.Deployment) b
if deploymentStatus(item) != v {
return false
}
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -80,10 +94,6 @@ func (*deploymentSearcher) fuzzy(fuzzy map[string]string, item *v1.Deployment) b
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -96,7 +106,7 @@ func (*deploymentSearcher) fuzzy(fuzzy map[string]string, item *v1.Deployment) b
func (*deploymentSearcher) compare(a, b *v1.Deployment, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -31,6 +31,10 @@ import (
type ingressSearcher struct {
}
func (*ingressSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Extensions().V1beta1().Ingresses().Lister().Ingresses(namespace).Get(name)
}
// exactly Match
func (*ingressSearcher) match(match map[string]string, item *extensions.Ingress) bool {
for k, v := range match {
@@ -39,8 +43,14 @@ func (*ingressSearcher) match(match map[string]string, item *extensions.Ingress)
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -67,10 +77,6 @@ func (*ingressSearcher) fuzzy(fuzzy map[string]string, item *extensions.Ingress)
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -82,7 +88,7 @@ func (*ingressSearcher) fuzzy(fuzzy map[string]string, item *extensions.Ingress)
func (*ingressSearcher) compare(a, b *extensions.Ingress, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -32,6 +32,10 @@ import (
type jobSearcher struct {
}
func (*jobSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Batch().V1().Jobs().Lister().Jobs(namespace).Get(name)
}
func jobStatus(item *batchv1.Job) string {
status := ""
@@ -54,8 +58,18 @@ func (*jobSearcher) match(match map[string]string, item *batchv1.Job) bool {
if jobStatus(item) != v {
return false
}
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -82,10 +96,6 @@ func (*jobSearcher) fuzzy(fuzzy map[string]string, item *batchv1.Job) bool {
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -111,6 +121,8 @@ func jobUpdateTime(item *batchv1.Job) time.Time {
func (*jobSearcher) compare(a, b *batchv1.Job, orderBy string) bool {
switch orderBy {
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case updateTime:
return jobUpdateTime(a).Before(jobUpdateTime(b))
case name:

View File

@@ -30,6 +30,10 @@ import (
type namespaceSearcher struct {
}
func (*namespaceSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Core().V1().Namespaces().Lister().Get(name)
}
// exactly Match
func (*namespaceSearcher) match(match map[string]string, item *v1.Namespace) bool {
for k, v := range match {
@@ -38,8 +42,14 @@ func (*namespaceSearcher) match(match map[string]string, item *v1.Namespace) boo
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -66,10 +76,6 @@ func (*namespaceSearcher) fuzzy(fuzzy map[string]string, item *v1.Namespace) boo
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -81,7 +87,7 @@ func (*namespaceSearcher) fuzzy(fuzzy map[string]string, item *v1.Namespace) boo
func (*namespaceSearcher) compare(a, b *v1.Namespace, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough
@@ -90,7 +96,7 @@ func (*namespaceSearcher) compare(a, b *v1.Namespace, orderBy string) bool {
}
}
func (s *namespaceSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
func (s *namespaceSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
namespaces, err := informers.SharedInformerFactory().Core().V1().Namespaces().Lister().List(labels.Everything())
if err != nil {

View File

@@ -30,6 +30,10 @@ import (
type nodeSearcher struct {
}
func (*nodeSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Core().V1().Nodes().Lister().Get(name)
}
// exactly Match
func (*nodeSearcher) match(match map[string]string, item *v1.Node) bool {
for k, v := range match {
@@ -38,8 +42,14 @@ func (*nodeSearcher) match(match map[string]string, item *v1.Node) bool {
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -66,10 +76,6 @@ func (*nodeSearcher) fuzzy(fuzzy map[string]string, item *v1.Node) bool {
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -81,7 +87,7 @@ func (*nodeSearcher) fuzzy(fuzzy map[string]string, item *v1.Node) bool {
func (*nodeSearcher) compare(a, b *v1.Node, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough
@@ -90,7 +96,7 @@ func (*nodeSearcher) compare(a, b *v1.Node, orderBy string) bool {
}
}
func (s *nodeSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
func (s *nodeSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
nodes, err := informers.SharedInformerFactory().Core().V1().Nodes().Lister().List(labels.Everything())
if err != nil {

View File

@@ -30,6 +30,10 @@ import (
type persistentVolumeClaimSearcher struct {
}
func (*persistentVolumeClaimSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Core().V1().PersistentVolumeClaims().Lister().PersistentVolumeClaims(namespace).Get(name)
}
// exactly Match
func (*persistentVolumeClaimSearcher) match(match map[string]string, item *v1.PersistentVolumeClaim) bool {
for k, v := range match {
@@ -38,8 +42,14 @@ func (*persistentVolumeClaimSearcher) match(match map[string]string, item *v1.Pe
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -66,10 +76,6 @@ func (*persistentVolumeClaimSearcher) fuzzy(fuzzy map[string]string, item *v1.Pe
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -81,7 +87,7 @@ func (*persistentVolumeClaimSearcher) fuzzy(fuzzy map[string]string, item *v1.Pe
func (*persistentVolumeClaimSearcher) compare(a, b *v1.PersistentVolumeClaim, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -31,25 +31,29 @@ import (
type podSearcher struct {
}
func podBelongTo(item *v1.Pod, kind string, name string) bool {
func (*podSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Core().V1().Pods().Lister().Pods(namespace).Get(name)
}
if strings.EqualFold(kind, "Deployment") {
func podBelongTo(item *v1.Pod, kind string, name string) bool {
switch kind {
case "Deployment":
if podBelongToDeployment(item, name) {
return true
}
} else if strings.EqualFold(kind, "ReplicaSet") {
case "ReplicaSet":
if podBelongToReplicaSet(item, name) {
return true
}
} else if strings.EqualFold(kind, "DaemonSet") {
case "DaemonSet":
if podBelongToDaemonSet(item, name) {
return true
}
} else if strings.EqualFold(kind, "StatefulSet") {
case "StatefulSet":
if podBelongToStatefulSet(item, name) {
return true
}
} else if strings.EqualFold(kind, "Job") {
case "Job":
if podBelongToJob(item, name) {
return true
}
@@ -57,9 +61,9 @@ func podBelongTo(item *v1.Pod, kind string, name string) bool {
return false
}
func replicaSetBelongToDeployment(replicaSet *v12.ReplicaSet, name string) bool {
func replicaSetBelongToDeployment(replicaSet *v12.ReplicaSet, deploymentName string) bool {
for _, owner := range replicaSet.OwnerReferences {
if owner.Kind == "Deployment" && owner.Name == name {
if owner.Kind == "Deployment" && owner.Name == deploymentName {
return true
}
}
@@ -84,38 +88,36 @@ func podBelongToJob(item *v1.Pod, name string) bool {
return false
}
func podBelongToReplicaSet(item *v1.Pod, name string) bool {
func podBelongToReplicaSet(item *v1.Pod, replicaSetName string) bool {
for _, owner := range item.OwnerReferences {
if owner.Kind == "ReplicaSet" && owner.Name == name {
if owner.Kind == "ReplicaSet" && owner.Name == replicaSetName {
return true
}
}
return false
}
func podBelongToStatefulSet(item *v1.Pod, name string) bool {
replicas, err := informers.SharedInformerFactory().Apps().V1().ReplicaSets().Lister().ReplicaSets(item.Namespace).List(labels.Everything())
if err != nil {
return false
}
for _, r := range replicas {
if replicaSetBelongToDeployment(r, name) {
return podBelongToReplicaSet(item, r.Name)
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 podBelongToDeployment(item *v1.Pod, name string) bool {
func podBelongToDeployment(item *v1.Pod, deploymentName string) bool {
replicas, err := informers.SharedInformerFactory().Apps().V1().ReplicaSets().Lister().ReplicaSets(item.Namespace).List(labels.Everything())
if err != nil {
return false
}
for _, r := range replicas {
if replicaSetBelongToDeployment(r, name) {
return podBelongToReplicaSet(item, r.Name)
if replicaSetBelongToDeployment(r, deploymentName) && podBelongToReplicaSet(item, r.Name) {
return true
}
}
return false
}
@@ -134,10 +136,10 @@ func podBelongToService(item *v1.Pod, serviceName string) bool {
if err != nil {
return false
}
for k, v := range service.Spec.Selector {
if item.Labels[k] != v {
return false
}
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
if !selector.Matches(labels.Set(item.Labels)) {
return false
}
return true
}
@@ -146,11 +148,11 @@ func podBelongToService(item *v1.Pod, serviceName string) bool {
func (*podSearcher) match(match map[string]string, item *v1.Pod) bool {
for k, v := range match {
switch k {
case "ownerKind":
case ownerKind:
fallthrough
case "ownerName":
kind := match["ownerKind"]
name := match["ownerName"]
case ownerName:
kind := match[ownerKind]
name := match[ownerName]
if !podBelongTo(item, kind, name) {
return false
}
@@ -170,6 +172,10 @@ func (*podSearcher) match(match map[string]string, item *v1.Pod) bool {
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if item.Labels[k] != v {
return false
@@ -200,10 +206,6 @@ func (*podSearcher) fuzzy(fuzzy map[string]string, item *v1.Pod) bool {
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -215,7 +217,7 @@ func (*podSearcher) fuzzy(fuzzy map[string]string, item *v1.Pod) bool {
func (*podSearcher) compare(a, b *v1.Pod, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -21,39 +21,45 @@ import (
"fmt"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"strings"
)
func init() {
namespacedResources[ConfigMaps] = &configMapSearcher{}
namespacedResources[CronJobs] = &cronJobSearcher{}
namespacedResources[DaemonSets] = &daemonSetSearcher{}
namespacedResources[Deployments] = &deploymentSearcher{}
namespacedResources[Ingresses] = &ingressSearcher{}
namespacedResources[Jobs] = &jobSearcher{}
namespacedResources[PersistentVolumeClaims] = &persistentVolumeClaimSearcher{}
namespacedResources[Secrets] = &secretSearcher{}
namespacedResources[Services] = &serviceSearcher{}
namespacedResources[StatefulSets] = &statefulSetSearcher{}
namespacedResources[Pods] = &podSearcher{}
namespacedResources[Roles] = &roleSearcher{}
namespacedResources[S2iBuilders] = &s2iBuilderSearcher{}
namespacedResources[S2iRuns] = &s2iRunSearcher{}
resources[ConfigMaps] = &configMapSearcher{}
resources[CronJobs] = &cronJobSearcher{}
resources[DaemonSets] = &daemonSetSearcher{}
resources[Deployments] = &deploymentSearcher{}
resources[Ingresses] = &ingressSearcher{}
resources[Jobs] = &jobSearcher{}
resources[PersistentVolumeClaims] = &persistentVolumeClaimSearcher{}
resources[Secrets] = &secretSearcher{}
resources[Services] = &serviceSearcher{}
resources[StatefulSets] = &statefulSetSearcher{}
resources[Pods] = &podSearcher{}
resources[Roles] = &roleSearcher{}
resources[S2iBuilders] = &s2iBuilderSearcher{}
resources[S2iRuns] = &s2iRunSearcher{}
clusterResources[Nodes] = &nodeSearcher{}
clusterResources[Namespaces] = &namespaceSearcher{}
clusterResources[ClusterRoles] = &clusterRoleSearcher{}
clusterResources[StorageClasses] = &storageClassesSearcher{}
clusterResources[S2iBuilderTemplates] = &s2iBuilderTemplateSearcher{}
resources[Nodes] = &nodeSearcher{}
resources[Namespaces] = &namespaceSearcher{}
resources[ClusterRoles] = &clusterRoleSearcher{}
resources[StorageClasses] = &storageClassesSearcher{}
resources[S2iBuilderTemplates] = &s2iBuilderTemplateSearcher{}
resources[Workspaces] = &workspaceSearcher{}
}
var namespacedResources = make(map[string]namespacedSearcherInterface)
var clusterResources = make(map[string]clusterSearcherInterface)
var (
resources = make(map[string]resourceSearchInterface)
clusterResources = []string{Nodes, Workspaces, Namespaces, ClusterRoles, StorageClasses, S2iBuilderTemplates}
)
const (
name = "name"
label = "label"
createTime = "createTime"
ownerKind = "ownerKind"
ownerName = "ownerName"
CreateTime = "CreateTime"
updateTime = "updateTime"
lastScheduleTime = "lastScheduleTime"
displayName = "displayName"
@@ -72,6 +78,8 @@ const (
Deployments = "deployments"
DaemonSets = "daemonsets"
Roles = "roles"
Workspaces = "workspaces"
WorkspaceRoles = "workspaceroles"
CronJobs = "cronjobs"
ConfigMaps = "configmaps"
Ingresses = "ingresses"
@@ -90,72 +98,58 @@ const (
S2iRuns = "s2iruns"
)
type namespacedSearcherInterface interface {
type resourceSearchInterface interface {
get(namespace, name string) (interface{}, error)
search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error)
}
type clusterSearcherInterface interface {
search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error)
func ListResourcesByName(namespace, resource string, names []string) (*models.PageableResponse, error) {
items := make([]interface{}, 0)
if searcher, ok := resources[resource]; ok {
for _, name := range names {
item, err := searcher.get(namespace, name)
if err != nil {
return nil, err
}
items = append(items, item)
}
} else {
return nil, fmt.Errorf("not found")
}
return &models.PageableResponse{TotalCount: len(items), Items: items}, nil
}
func ListNamespaceResource(namespace, resource string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
func ListResources(namespace, resource string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
items := make([]interface{}, 0)
total := 0
var err error
var result []interface{}
if searcher, ok := namespacedResources[resource]; ok {
// none namespace resource
if namespace != "" && sliceutil.HasString(clusterResources, resource) {
return nil, fmt.Errorf("not found")
}
if searcher, ok := resources[resource]; ok {
result, err = searcher.search(namespace, conditions, orderBy, reverse)
} else {
return nil, fmt.Errorf("not support")
return nil, fmt.Errorf("not found")
}
if err != nil {
return nil, err
}
total = len(result)
for i, d := range result {
if i >= offset && (limit == -1 || len(items) < limit) {
items = append(items, d)
}
}
return &models.PageableResponse{TotalCount: total, Items: items}, nil
}
func ListClusterResource(resource string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
items := make([]interface{}, 0)
total := 0
var err error
if err != nil {
return nil, err
}
var result []interface{}
if searcher, ok := clusterResources[resource]; ok {
result, err = searcher.search(conditions, orderBy, reverse)
} else if searcher, ok := namespacedResources[resource]; ok {
result, err = searcher.search("", conditions, orderBy, reverse)
} else {
return nil, fmt.Errorf("not support")
}
if err != nil {
return nil, err
}
total = len(result)
for i, d := range result {
if i >= offset && len(items) < limit {
items = append(items, d)
}
}
return &models.PageableResponse{TotalCount: total, Items: items}, nil
return &models.PageableResponse{TotalCount: len(result), Items: items}, nil
}
func searchFuzzy(m map[string]string, key, value string) bool {

View File

@@ -30,6 +30,10 @@ import (
type roleSearcher struct {
}
func (*roleSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().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 {
@@ -38,8 +42,14 @@ func (*roleSearcher) match(match map[string]string, item *rbac.Role) bool {
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -62,10 +72,6 @@ func (*roleSearcher) fuzzy(fuzzy map[string]string, item *rbac.Role) bool {
return false
}
return false
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -77,7 +83,7 @@ func (*roleSearcher) fuzzy(fuzzy map[string]string, item *rbac.Role) bool {
func (*roleSearcher) compare(a, b *rbac.Role, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -30,6 +30,10 @@ import (
type s2iBuilderSearcher struct {
}
func (*s2iBuilderSearcher) get(namespace, name string) (interface{}, error) {
return informers.S2iSharedInformerFactory().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 {
@@ -38,8 +42,14 @@ func (*s2iBuilderSearcher) match(match map[string]string, item *v1alpha1.S2iBuil
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -66,10 +76,6 @@ func (*s2iBuilderSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iBuil
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -81,7 +87,7 @@ func (*s2iBuilderSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iBuil
func (*s2iBuilderSearcher) compare(a, b *v1alpha1.S2iBuilder, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -30,6 +30,10 @@ import (
type s2iBuilderTemplateSearcher struct {
}
func (*s2iBuilderTemplateSearcher) get(namespace, name string) (interface{}, error) {
return informers.S2iSharedInformerFactory().Devops().V1alpha1().S2iBuilderTemplates().Lister().Get(name)
}
// exactly Match
func (*s2iBuilderTemplateSearcher) match(match map[string]string, item *v1alpha1.S2iBuilderTemplate) bool {
for k, v := range match {
@@ -38,8 +42,14 @@ func (*s2iBuilderTemplateSearcher) match(match map[string]string, item *v1alpha1
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -62,10 +72,6 @@ func (*s2iBuilderTemplateSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1
return false
}
return false
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -77,7 +83,7 @@ func (*s2iBuilderTemplateSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1
func (*s2iBuilderTemplateSearcher) compare(a, b *v1alpha1.S2iBuilderTemplate, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough
@@ -86,7 +92,7 @@ func (*s2iBuilderTemplateSearcher) compare(a, b *v1alpha1.S2iBuilderTemplate, or
}
}
func (s *s2iBuilderTemplateSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
func (s *s2iBuilderTemplateSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
builderTemplates, err := informers.S2iSharedInformerFactory().Devops().V1alpha1().S2iBuilderTemplates().Lister().List(labels.Everything())
if err != nil {

View File

@@ -33,6 +33,10 @@ import (
type s2iRunSearcher struct {
}
func (*s2iRunSearcher) get(namespace, name string) (interface{}, error) {
return informers.S2iSharedInformerFactory().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 {
@@ -42,11 +46,17 @@ func (*s2iRunSearcher) match(match map[string]string, item *v1alpha1.S2iRun) boo
return false
}
case status:
if string(item.Status.RunState) != v{
if string(item.Status.RunState) != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -73,10 +83,6 @@ func (*s2iRunSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iRun) boo
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -88,7 +94,7 @@ func (*s2iRunSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iRun) boo
func (*s2iRunSearcher) compare(a, b *v1alpha1.S2iRun, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -30,6 +30,10 @@ import (
type secretSearcher struct {
}
func (*secretSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().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 {
@@ -42,8 +46,14 @@ func (*secretSearcher) match(match map[string]string, item *v1.Secret) bool {
if string(item.Type) != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -70,10 +80,6 @@ func (*secretSearcher) fuzzy(fuzzy map[string]string, item *v1.Secret) bool {
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -85,7 +91,7 @@ func (*secretSearcher) fuzzy(fuzzy map[string]string, item *v1.Secret) bool {
func (*secretSearcher) compare(a, b *v1.Secret, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -30,6 +30,10 @@ import (
type serviceSearcher struct {
}
func (*serviceSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().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 {
@@ -38,8 +42,14 @@ func (*serviceSearcher) match(match map[string]string, item *v1.Service) bool {
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -66,10 +76,6 @@ func (*serviceSearcher) fuzzy(fuzzy map[string]string, item *v1.Service) bool {
if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -81,7 +87,7 @@ func (*serviceSearcher) fuzzy(fuzzy map[string]string, item *v1.Service) bool {
func (*serviceSearcher) compare(a, b *v1.Service, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -30,6 +30,10 @@ import (
type statefulSetSearcher struct {
}
func (*statefulSetSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().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 {
@@ -52,7 +56,9 @@ func (*statefulSetSearcher) match(match map[string]string, item *v1.StatefulSet)
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -95,7 +101,7 @@ func (*statefulSetSearcher) fuzzy(fuzzy map[string]string, item *v1.StatefulSet)
func (*statefulSetSearcher) compare(a, b *v1.StatefulSet, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough

View File

@@ -30,6 +30,10 @@ import (
type storageClassesSearcher struct {
}
func (*storageClassesSearcher) get(namespace, name string) (interface{}, error) {
return informers.SharedInformerFactory().Storage().V1().StorageClasses().Lister().Get(name)
}
// exactly Match
func (*storageClassesSearcher) match(match map[string]string, item *v1.StorageClass) bool {
for k, v := range match {
@@ -38,8 +42,14 @@ func (*storageClassesSearcher) match(match map[string]string, item *v1.StorageCl
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
return false
if item.Labels[k] != v {
return false
}
}
}
return true
@@ -62,10 +72,6 @@ func (*storageClassesSearcher) fuzzy(fuzzy map[string]string, item *v1.StorageCl
return false
}
return false
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
@@ -77,7 +83,7 @@ func (*storageClassesSearcher) fuzzy(fuzzy map[string]string, item *v1.StorageCl
func (*storageClassesSearcher) compare(a, b *v1.StorageClass, orderBy string) bool {
switch orderBy {
case createTime:
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case name:
fallthrough
@@ -86,7 +92,7 @@ func (*storageClassesSearcher) compare(a, b *v1.StorageClass, orderBy string) bo
}
}
func (s *storageClassesSearcher) search(conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
func (s *storageClassesSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
storageClasses, err := informers.SharedInformerFactory().Storage().V1().StorageClasses().Lister().List(labels.Everything())
if err != nil {

View File

@@ -0,0 +1,132 @@
/*
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 resources
import (
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/params"
"sort"
"strings"
"k8s.io/apimachinery/pkg/labels"
)
type workspaceSearcher struct {
}
func (*workspaceSearcher) get(namespace, name string) (interface{}, error) {
return informers.KsSharedInformerFactory().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 name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
case keyword:
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
return false
}
default:
if item.Labels[k] != 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 name:
if !strings.Contains(item.Name, v) && !strings.Contains(item.Labels[displayName], v) {
return false
}
case label:
if !searchFuzzy(item.Labels, "", v) {
return false
}
case annotation:
if !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 !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
return false
}
}
}
return true
}
func (*workspaceSearcher) compare(a, b *tenantv1alpha1.Workspace, orderBy string) bool {
switch orderBy {
case CreateTime:
return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
case 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 := informers.KsSharedInformerFactory().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
}