Initial commit

This commit is contained in:
jeff
2019-03-07 17:08:54 +08:00
commit 47bf8820f4
2817 changed files with 960937 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
/*
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 (
"sort"
"strings"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/listers/rbac/v1"
)
type clusterRoleSearcher struct {
clusterRoleLister v1.ClusterRoleLister
}
// exactly match
func (*clusterRoleSearcher) match(match map[string]string, item *rbac.ClusterRole) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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 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
}
}
}
return true
}
func (*clusterRoleSearcher) compare(a, b *rbac.ClusterRole, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *clusterRoleSearcher) search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
clusterRoles, err := s.clusterRoleLister.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
}

View File

@@ -0,0 +1,126 @@
/*
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 (
"sort"
"strings"
lister "k8s.io/client-go/listers/core/v1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
type configMapSearcher struct {
configMapLister lister.ConfigMapLister
}
// exactly match
func (*configMapSearcher) match(match map[string]string, item *v1.ConfigMap) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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
}
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
}
}
}
return true
}
func (*configMapSearcher) compare(a, b *v1.ConfigMap, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *configMapSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
configMaps, err := s.configMapLister.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 {
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,134 @@
/*
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 (
"sort"
"strings"
lister "k8s.io/client-go/listers/batch/v2alpha1"
"k8s.io/api/batch/v2alpha1"
"k8s.io/apimachinery/pkg/labels"
)
type cronJobSearcher struct {
cronJobLister lister.CronJobLister
}
func cronJobStatus(item *v2alpha1.CronJob) string {
if item.Spec.Suspend != nil && *item.Spec.Suspend {
return paused
}
return running
}
// Exactly match
func (*cronJobSearcher) match(match map[string]string, item *v2alpha1.CronJob) bool {
for k, v := range match {
switch k {
case status:
if cronJobStatus(item) != v {
return false
}
default:
return false
}
}
return true
}
func (*cronJobSearcher) fuzzy(fuzzy map[string]string, item *v2alpha1.CronJob) 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
}
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
}
}
}
return true
}
func (*cronJobSearcher) compare(a, b *v2alpha1.CronJob, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *cronJobSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
cronJobs, err := s.cronJobLister.CronJobs(namespace).List(labels.Everything())
if err != nil {
return nil, err
}
result := make([]*v2alpha1.CronJob, 0)
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
result = cronJobs
} else {
for _, item := range cronJobs {
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
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 resources
import (
"sort"
"strings"
lister "k8s.io/client-go/listers/apps/v1"
"k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/labels"
)
type daemonSetSearcher struct {
daemonSetLister lister.DaemonSetLister
}
func daemonSetStatus(item *v1.DaemonSet) string {
if item.Status.NumberAvailable == 0 {
return stopped
} else if item.Status.DesiredNumberScheduled == item.Status.NumberAvailable {
return running
} else {
return updating
}
}
// Exactly match
func (*daemonSetSearcher) match(match map[string]string, item *v1.DaemonSet) bool {
for k, v := range match {
switch k {
case status:
if daemonSetStatus(item) != v {
return false
}
default:
return false
}
}
return true
}
func (*daemonSetSearcher) fuzzy(fuzzy map[string]string, item *v1.DaemonSet) 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
}
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
}
}
}
return true
}
func (*daemonSetSearcher) compare(a, b *v1.DaemonSet, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *daemonSetSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
daemonSets, err := s.daemonSetLister.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 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,141 @@
/*
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 (
"sort"
"strings"
lister "k8s.io/client-go/listers/apps/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/api/apps/v1"
)
type deploymentSearcher struct {
deploymentLister lister.DeploymentLister
}
func deploymentStatus(item *v1.Deployment) string {
if item.Spec.Replicas != nil {
if item.Status.ReadyReplicas == 0 && *item.Spec.Replicas == 0 {
return stopped
} else if item.Status.ReadyReplicas == *item.Spec.Replicas {
return running
} else {
return updating
}
}
return stopped
}
// Exactly match
func (*deploymentSearcher) match(match map[string]string, item *v1.Deployment) bool {
for k, v := range match {
switch k {
case status:
if deploymentStatus(item) != v {
return false
}
default:
return false
}
}
return true
}
func (*deploymentSearcher) fuzzy(fuzzy map[string]string, item *v1.Deployment) 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
}
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
}
}
}
return true
}
func (*deploymentSearcher) compare(a, b *v1.Deployment, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *deploymentSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
deployments, err := s.deploymentLister.Deployments(namespace).List(labels.Everything())
if err != nil {
return nil, err
}
result := make([]*v1.Deployment, 0)
if len(conditions.match) == 0 && len(conditions.fuzzy) == 0 {
result = deployments
} else {
for _, item := range deployments {
if s.match(conditions.match, item) && s.fuzzy(conditions.fuzzy, item) {
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,127 @@
/*
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 (
"sort"
"strings"
lister "k8s.io/client-go/listers/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/labels"
)
type ingressSearcher struct {
ingressLister lister.IngressLister
}
// exactly match
func (*ingressSearcher) match(match map[string]string, item *extensions.Ingress) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
return false
}
}
return true
}
// fuzzy searchInNamespace
func (*ingressSearcher) fuzzy(fuzzy map[string]string, item *extensions.Ingress) 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
}
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
}
}
}
return true
}
func (*ingressSearcher) compare(a, b *extensions.Ingress, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *ingressSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
ingresses, err := s.ingressLister.Ingresses(namespace).List(labels.Everything())
if err != nil {
return nil, err
}
result := make([]*extensions.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,156 @@
/*
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 (
"sort"
"strings"
"time"
lister "k8s.io/client-go/listers/batch/v1"
batchV1 "k8s.io/api/batch/v1"
coreV1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
type jobSearcher struct {
jobLister lister.JobLister
}
func jobStatus(item *batchV1.Job) string {
status := ""
for _, condition := range item.Status.Conditions {
if condition.Type == batchV1.JobFailed && condition.Status == coreV1.ConditionTrue {
status = failed
}
if condition.Type == batchV1.JobComplete && condition.Status == coreV1.ConditionTrue {
status = complete
}
}
return status
}
// Exactly match
func (*jobSearcher) match(match map[string]string, item *batchV1.Job) bool {
for k, v := range match {
switch k {
case status:
if jobStatus(item) != v {
return false
}
default:
return false
}
}
return true
}
func (*jobSearcher) fuzzy(fuzzy map[string]string, item *batchV1.Job) 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
}
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
}
}
}
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 updateTime:
return jobUpdateTime(a).After(jobUpdateTime(b))
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *jobSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
jobs, err := s.jobLister.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,125 @@
/*
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 (
"sort"
"strings"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
lister "k8s.io/client-go/listers/core/v1"
)
type namespaceSearcher struct {
namespaceLister lister.NamespaceLister
}
// exactly match
func (*namespaceSearcher) match(match map[string]string, item *v1.Namespace) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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
}
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
}
}
}
return true
}
func (*namespaceSearcher) compare(a, b *v1.Namespace, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *namespaceSearcher) search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
namespaces, err := s.namespaceLister.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,125 @@
/*
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 (
"sort"
"strings"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
lister "k8s.io/client-go/listers/core/v1"
)
type nodeSearcher struct {
nodeLister lister.NodeLister
}
// exactly match
func (*nodeSearcher) match(match map[string]string, item *v1.Node) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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
}
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
}
}
}
return true
}
func (*nodeSearcher) compare(a, b *v1.Node, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *nodeSearcher) search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
nodes, err := s.nodeLister.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,126 @@
/*
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 (
"sort"
"strings"
lister "k8s.io/client-go/listers/core/v1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
type persistentVolumeClaimSearcher struct {
persistentVolumeClaimLister lister.PersistentVolumeClaimLister
}
// exactly match
func (*persistentVolumeClaimSearcher) match(match map[string]string, item *v1.PersistentVolumeClaim) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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
}
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
}
}
}
return true
}
func (*persistentVolumeClaimSearcher) compare(a, b *v1.PersistentVolumeClaim, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *persistentVolumeClaimSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
persistentVolumeClaims, err := s.persistentVolumeClaimLister.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 {
r = append(r, i)
}
return r, nil
}

View File

@@ -0,0 +1,127 @@
/*
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 (
"sort"
"strings"
v12 "k8s.io/client-go/listers/core/v1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
type podSearcher struct {
podLister v12.PodLister
}
// exactly match
func (*podSearcher) match(match map[string]string, item *v1.Pod) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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
}
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
}
}
}
return true
}
func (*podSearcher) compare(a, b *v1.Pod, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *podSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
pods, err := s.podLister.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,240 @@
/*
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 (
"regexp"
"strings"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/errors"
)
func init() {
namespacedResources[ConfigMaps] = &configMapSearcher{
configMapLister: informers.SharedInformerFactory().Core().V1().ConfigMaps().Lister(),
}
namespacedResources[CronJobs] = &cronJobSearcher{
cronJobLister: informers.SharedInformerFactory().Batch().V2alpha1().CronJobs().Lister(),
}
namespacedResources[DaemonSets] = &daemonSetSearcher{
daemonSetLister: informers.SharedInformerFactory().Apps().V1().DaemonSets().Lister(),
}
namespacedResources[Deployments] = &deploymentSearcher{
deploymentLister: informers.SharedInformerFactory().Apps().V1().Deployments().Lister(),
}
namespacedResources[Ingresses] = &ingressSearcher{
ingressLister: informers.SharedInformerFactory().Extensions().V1beta1().Ingresses().Lister(),
}
namespacedResources[Jobs] = &jobSearcher{
jobLister: informers.SharedInformerFactory().Batch().V1().Jobs().Lister(),
}
namespacedResources[PersistentVolumeClaims] = &persistentVolumeClaimSearcher{
persistentVolumeClaimLister: informers.SharedInformerFactory().Core().V1().PersistentVolumeClaims().Lister(),
}
namespacedResources[Secrets] = &secretSearcher{
secretLister: informers.SharedInformerFactory().Core().V1().Secrets().Lister(),
}
namespacedResources[Services] = &serviceSearcher{
serviceLister: informers.SharedInformerFactory().Core().V1().Services().Lister(),
}
namespacedResources[StatefulSets] = &statefulSetSearcher{
statefulSetLister: informers.SharedInformerFactory().Apps().V1().StatefulSets().Lister(),
}
namespacedResources[Pods] = &podSearcher{
podLister: informers.SharedInformerFactory().Core().V1().Pods().Lister(),
}
namespacedResources[Roles] = &roleSearcher{
roleLister: informers.SharedInformerFactory().Rbac().V1().Roles().Lister(),
}
clusterResources[Nodes] = &nodeSearcher{
nodeLister: informers.SharedInformerFactory().Core().V1().Nodes().Lister(),
}
clusterResources[Namespaces] = &namespaceSearcher{
namespaceLister: informers.SharedInformerFactory().Core().V1().Namespaces().Lister(),
}
clusterResources[ClusterRoles] = &clusterRoleSearcher{
clusterRoleLister: informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister(),
}
clusterResources[StorageClasses] = &storageClassesSearcher{
storageClassesLister: informers.SharedInformerFactory().Storage().V1().StorageClasses().Lister(),
}
}
var namespacedResources = make(map[string]namespacedSearcherInterface)
var clusterResources = make(map[string]clusterSearcherInterface)
type conditions struct {
match map[string]string
fuzzy map[string]string
}
const (
name = "name"
label = "label"
createTime = "createTime"
updateTime = "updateTime"
displayName = "displayName"
chart = "chart"
release = "release"
annotation = "annotation"
keyword = "keyword"
status = "status"
running = "running"
paused = "paused"
updating = "updating"
stopped = "stopped"
failed = "failed"
complete = "complete"
app = "app"
Deployments = "deployments"
DaemonSets = "daemonsets"
Roles = "roles"
CronJobs = "cronjobs"
ConfigMaps = "configmaps"
Ingresses = "ingresses"
Jobs = "jobs"
PersistentVolumeClaims = "persistentvolumeclaims"
Pods = "pods"
Secrets = "secrets"
Services = "services"
StatefulSets = "statefulsets"
Nodes = "nodes"
Namespaces = "namespaces"
StorageClasses = "storageclasses"
ClusterRoles = "clusterroles"
)
type namespacedSearcherInterface interface {
search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error)
}
type clusterSearcherInterface interface {
search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error)
}
func ListNamespaceResource(namespace, resource, conditionStr, orderBy string, reverse bool, limit, offset int) (*ResourceList, error) {
items := make([]interface{}, 0)
total := 0
var err error
conditions, err := parseToConditions(conditionStr)
if err != nil {
return nil, err
}
var result []interface{}
if searcher, ok := namespacedResources[resource]; ok {
result, err = searcher.search(namespace, conditions, orderBy, reverse)
} else {
return nil, errors.New(errors.NotImplement, "not support")
}
if err != nil {
return nil, errors.New(errors.Internal, err.Error())
}
total = len(result)
for i, d := range result {
if i >= offset && (limit == -1 || len(items) < limit) {
items = append(items, d)
}
}
return &ResourceList{TotalCount: total, Items: items}, nil
}
func ListClusterResource(resource, conditionStr, orderBy string, reverse bool, limit, offset int) (*ResourceList, error) {
items := make([]interface{}, 0)
total := 0
var err error
conditions, err := parseToConditions(conditionStr)
if err != nil {
return nil, err
}
var result []interface{}
if searcher, ok := clusterResources[resource]; ok {
result, err = searcher.search(conditions, orderBy, reverse)
} else {
return nil, errors.New(errors.NotImplement, "not support")
}
if err != nil {
return nil, errors.New(errors.Internal, err.Error())
}
total = len(result)
for i, d := range result {
if i >= offset && len(items) < limit {
items = append(items, d)
}
}
return &ResourceList{TotalCount: total, Items: items}, nil
}
func parseToConditions(str string) (*conditions, error) {
conditions := &conditions{match: make(map[string]string, 0), fuzzy: make(map[string]string, 0)}
if str == "" {
return conditions, nil
}
for _, item := range strings.Split(str, ",") {
if strings.Count(item, "=") > 1 || strings.Count(item, "~") > 1 {
return nil, errors.New(errors.InvalidArgument, "invalid condition")
}
if groups := regexp.MustCompile(`(\S+)([=~])(\S+)`).FindStringSubmatch(item); len(groups) == 4 {
if groups[2] == "=" {
conditions.match[groups[1]] = groups[3]
} else {
conditions.fuzzy[groups[1]] = groups[3]
}
} else {
return nil, errors.New(errors.InvalidArgument, "invalid condition")
}
}
return conditions, nil
}
type ResourceList struct {
TotalCount int `json:"total_count"`
Items []interface{} `json:"items"`
}
func searchFuzzy(m map[string]string, key, value string) bool {
for k, v := range m {
if key == "" {
if strings.Contains(k, value) || strings.Contains(v, value) {
return true
}
} else if k == key && strings.Contains(v, value) {
return true
}
}
return false
}

View File

@@ -0,0 +1,122 @@
/*
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 (
"sort"
"strings"
rbac "k8s.io/api/rbac/v1"
lister "k8s.io/client-go/listers/rbac/v1"
"k8s.io/apimachinery/pkg/labels"
)
type roleSearcher struct {
roleLister lister.RoleLister
}
// exactly match
func (*roleSearcher) match(match map[string]string, item *rbac.Role) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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 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
}
}
}
return true
}
func (*roleSearcher) compare(a, b *rbac.Role, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *roleSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
roles, err := s.roleLister.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
}

View File

@@ -0,0 +1,130 @@
/*
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 (
"sort"
"strings"
lister "k8s.io/client-go/listers/core/v1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
type secretSearcher struct {
secretLister lister.SecretLister
}
// exactly match
func (*secretSearcher) match(match map[string]string, item *v1.Secret) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
case "type":
if string(item.Type) != v {
return false
}
default:
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 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
}
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
}
}
}
return true
}
func (*secretSearcher) compare(a, b *v1.Secret, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *secretSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
secrets, err := s.secretLister.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,126 @@
/*
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 (
"sort"
"strings"
lister "k8s.io/client-go/listers/core/v1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
type serviceSearcher struct {
serviceLister lister.ServiceLister
}
// exactly match
func (*serviceSearcher) match(match map[string]string, item *v1.Service) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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
}
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
}
}
}
return true
}
func (*serviceSearcher) compare(a, b *v1.Service, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *serviceSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
services, err := s.serviceLister.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,140 @@
/*
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 (
"sort"
"strings"
lister "k8s.io/client-go/listers/apps/v1"
"k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/labels"
)
type statefulSetSearcher struct {
statefulSetLister lister.StatefulSetLister
}
func statefulSetStatus(item *v1.StatefulSet) string {
if item.Spec.Replicas != nil {
if item.Status.ReadyReplicas == 0 && *item.Spec.Replicas == 0 {
return stopped
} else if item.Status.ReadyReplicas == *item.Spec.Replicas {
return running
} else {
return updating
}
}
return stopped
}
// Exactly match
func (*statefulSetSearcher) match(match map[string]string, item *v1.StatefulSet) bool {
for k, v := range match {
switch k {
case status:
if statefulSetStatus(item) != v {
return false
}
default:
return false
}
}
return true
}
func (*statefulSetSearcher) fuzzy(fuzzy map[string]string, item *v1.StatefulSet) 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
}
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
}
}
}
return true
}
func (*statefulSetSearcher) compare(a, b *v1.StatefulSet, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *statefulSetSearcher) search(namespace string, conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
statefulSets, err := s.statefulSetLister.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,121 @@
/*
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 (
"sort"
"strings"
"k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/labels"
lister "k8s.io/client-go/listers/storage/v1"
)
type storageClassesSearcher struct {
storageClassesLister lister.StorageClassLister
}
// exactly match
func (*storageClassesSearcher) match(match map[string]string, item *v1.StorageClass) bool {
for k, v := range match {
switch k {
case name:
if item.Name != v && item.Labels[displayName] != v {
return false
}
default:
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 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 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
}
}
}
return true
}
func (*storageClassesSearcher) compare(a, b *v1.StorageClass, orderBy string) bool {
switch orderBy {
case createTime:
return a.CreationTimestamp.Time.After(b.CreationTimestamp.Time)
case name:
fallthrough
default:
return strings.Compare(a.Name, b.Name) <= 0
}
}
func (s *storageClassesSearcher) search(conditions *conditions, orderBy string, reverse bool) ([]interface{}, error) {
storageClasses, err := s.storageClassesLister.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 {
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
}