feat: kubesphere 4.0 (#6115)
* feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> * feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> --------- Signed-off-by: ci-bot <ci-bot@kubesphere.io> Co-authored-by: ks-ci-bot <ks-ci-bot@example.com> Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
committed by
GitHub
parent
b5015ec7b9
commit
447a51f08b
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package clusterrole
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
)
|
||||
|
||||
type clusterRoleSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewClusterRoleSearcher(informer informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &clusterRoleSearcher{informer: informer}
|
||||
}
|
||||
|
||||
func (s *clusterRoleSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informer.Rbac().V1().ClusterRoles().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (*clusterRoleSearcher) match(match map[string]string, item *rbac.ClusterRole) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.OwnerKind:
|
||||
fallthrough
|
||||
case v1alpha2.OwnerName:
|
||||
kind := match[v1alpha2.OwnerKind]
|
||||
name := match[v1alpha2.OwnerName]
|
||||
if !k8sutil.IsControlledBy(item.OwnerReferences, kind, name) {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.UserFacing:
|
||||
if v == "true" {
|
||||
if !isUserFacingClusterRole(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *clusterRoleSearcher) fuzzy(fuzzy map[string]string, item *rbac.ClusterRole) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *clusterRoleSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
clusterRoles, err := s.informer.Rbac().V1().ClusterRoles().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*rbac.ClusterRole, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = clusterRoles
|
||||
} else {
|
||||
for _, item := range clusterRoles {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// cluster role created by user from kubesphere dashboard
|
||||
func isUserFacingClusterRole(role *rbac.ClusterRole) bool {
|
||||
if role.Annotations[constants.CreatorAnnotationKey] != "" && role.Labels[constants.WorkspaceLabelKey] == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configmap
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type configMapSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewConfigmapSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &configMapSearcher{informer: informers}
|
||||
}
|
||||
|
||||
func (s *configMapSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informer.Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (s *configMapSearcher) match(match map[string]string, item *v1.ConfigMap) bool {
|
||||
for k, v := range match {
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *configMapSearcher) fuzzy(fuzzy map[string]string, item *v1.ConfigMap) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *configMapSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
configMaps, err := s.informer.Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.ConfigMap, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = configMaps
|
||||
} else {
|
||||
for _, item := range configMaps {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cronjob
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/batch/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type cronJobSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewCronJobSearcher(informer informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &cronJobSearcher{informer: informer}
|
||||
}
|
||||
|
||||
func (c *cronJobSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return c.informer.Batch().V1().CronJobs().Lister().CronJobs(namespace).Get(name)
|
||||
}
|
||||
|
||||
func cronJobStatus(item *v1.CronJob) string {
|
||||
if item.Spec.Suspend != nil && *item.Spec.Suspend {
|
||||
return v1alpha2.StatusPaused
|
||||
}
|
||||
return v1alpha2.StatusRunning
|
||||
}
|
||||
|
||||
func (*cronJobSearcher) match(match map[string]string, item *v1.CronJob) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
if cronJobStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*cronJobSearcher) fuzzy(fuzzy map[string]string, item *v1.CronJob) bool {
|
||||
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (*cronJobSearcher) compare(left, right *v1.CronJob, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.LastScheduleTime:
|
||||
if left.Status.LastScheduleTime == nil {
|
||||
return true
|
||||
}
|
||||
if right.Status.LastScheduleTime == nil {
|
||||
return false
|
||||
}
|
||||
return left.Status.LastScheduleTime.Before(right.Status.LastScheduleTime)
|
||||
default:
|
||||
return v1alpha2.ObjectMetaCompare(left.ObjectMeta, right.ObjectMeta, orderBy)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cronJobSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
cronJobs, err := c.informer.Batch().V1().CronJobs().Lister().CronJobs(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.CronJob, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = cronJobs
|
||||
} else {
|
||||
for _, item := range cronJobs {
|
||||
if c.match(conditions.Match, item) && c.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
return !c.compare(result[i], result[j], orderBy)
|
||||
} else {
|
||||
return c.compare(result[i], result[j], orderBy)
|
||||
}
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for i := range result {
|
||||
r = append(r, result[i])
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package daemonset
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type daemonSetSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewDaemonSetSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &daemonSetSearcher{informer: informers}
|
||||
}
|
||||
|
||||
func (c *daemonSetSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return c.informer.Apps().V1().DaemonSets().Lister().DaemonSets(namespace).Get(name)
|
||||
}
|
||||
|
||||
func daemonSetStatus(item *v1.DaemonSet) string {
|
||||
if item.Status.DesiredNumberScheduled == 0 && item.Status.NumberReady == 0 {
|
||||
return v1alpha2.StatusStopped
|
||||
} else if item.Status.DesiredNumberScheduled == item.Status.NumberReady {
|
||||
return v1alpha2.StatusRunning
|
||||
} else {
|
||||
return v1alpha2.StatusUpdating
|
||||
}
|
||||
}
|
||||
|
||||
func (*daemonSetSearcher) match(match map[string]string, item *v1.DaemonSet) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
if daemonSetStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*daemonSetSearcher) fuzzy(kv map[string]string, item *v1.DaemonSet) bool {
|
||||
for k, v := range kv {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *daemonSetSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
daemonSets, err := c.informer.Apps().V1().DaemonSets().Lister().DaemonSets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.DaemonSet, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = daemonSets
|
||||
} else {
|
||||
for _, item := range daemonSets {
|
||||
if c.match(conditions.Match, item) && c.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
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 deployment
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
)
|
||||
|
||||
type deploymentSearcher struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewDeploymentSetSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &deploymentSearcher{informer: informers}
|
||||
}
|
||||
|
||||
func (s *deploymentSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informer.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 {
|
||||
return v1alpha2.StatusStopped
|
||||
} else if item.Status.ReadyReplicas == *item.Spec.Replicas {
|
||||
return v1alpha2.StatusRunning
|
||||
} else {
|
||||
return v1alpha2.StatusUpdating
|
||||
}
|
||||
}
|
||||
return v1alpha2.StatusStopped
|
||||
}
|
||||
|
||||
func (*deploymentSearcher) match(kv map[string]string, item *v1.Deployment) bool {
|
||||
for k, v := range kv {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
if deploymentStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*deploymentSearcher) fuzzy(kv map[string]string, item *v1.Deployment) bool {
|
||||
for k, v := range kv {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *deploymentSearcher) compare(a, b *v1.Deployment, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.UpdateTime:
|
||||
aLastUpdateTime := s.lastUpdateTime(a)
|
||||
bLastUpdateTime := s.lastUpdateTime(b)
|
||||
if aLastUpdateTime.Equal(bLastUpdateTime) {
|
||||
return strings.Compare(a.Name, b.Name) <= 0
|
||||
}
|
||||
return aLastUpdateTime.Before(bLastUpdateTime)
|
||||
default:
|
||||
return v1alpha2.ObjectMetaCompare(a.ObjectMeta, b.ObjectMeta, orderBy)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *deploymentSearcher) lastUpdateTime(deployment *v1.Deployment) time.Time {
|
||||
lastUpdateTime := deployment.CreationTimestamp.Time
|
||||
for _, condition := range deployment.Status.Conditions {
|
||||
if condition.LastUpdateTime.After(lastUpdateTime) {
|
||||
lastUpdateTime = condition.LastUpdateTime.Time
|
||||
}
|
||||
}
|
||||
return lastUpdateTime
|
||||
}
|
||||
|
||||
func (s *deploymentSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
deployments, err := s.informer.Apps().V1().Deployments().Lister().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 {
|
||||
i, j = j, i
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package hpa
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type hpaSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewHpaSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &hpaSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *hpaSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Autoscaling().V2().HorizontalPodAutoscalers().Lister().HorizontalPodAutoscalers(namespace).Get(name)
|
||||
}
|
||||
|
||||
func hpaTargetMatch(item *autoscalingv2.HorizontalPodAutoscaler, kind, name string) bool {
|
||||
return item.Spec.ScaleTargetRef.Kind == kind && item.Spec.ScaleTargetRef.Name == name
|
||||
}
|
||||
|
||||
// exactly Match
|
||||
func (*hpaSearcher) match(match map[string]string, item *autoscalingv2.HorizontalPodAutoscaler) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.TargetKind:
|
||||
fallthrough
|
||||
case v1alpha2.TargetName:
|
||||
kind := match[v1alpha2.TargetKind]
|
||||
name := match[v1alpha2.TargetName]
|
||||
if !hpaTargetMatch(item, kind, name) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*hpaSearcher) fuzzy(fuzzy map[string]string, item *autoscalingv2.HorizontalPodAutoscaler) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *hpaSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
|
||||
horizontalPodAutoscalers, err := s.informers.Autoscaling().V2().HorizontalPodAutoscalers().Lister().HorizontalPodAutoscalers(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*autoscalingv2.HorizontalPodAutoscaler, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = horizontalPodAutoscalers
|
||||
} else {
|
||||
for _, item := range horizontalPodAutoscalers {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package ingress
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type ingressSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewIngressSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &ingressSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *ingressSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Networking().V1().Ingresses().Lister().Ingresses(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (*ingressSearcher) match(match map[string]string, item *v1.Ingress) bool {
|
||||
for k, v := range match {
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*ingressSearcher) fuzzy(fuzzy map[string]string, item *v1.Ingress) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *ingressSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
ingresses, err := s.informers.Networking().V1().Ingresses().Lister().Ingresses(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.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 {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 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 v1alpha2
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
)
|
||||
|
||||
const (
|
||||
App = "app"
|
||||
Chart = "chart"
|
||||
Release = "release"
|
||||
Name = "name"
|
||||
Label = "label"
|
||||
OwnerKind = "ownerKind"
|
||||
OwnerName = "ownerName"
|
||||
TargetKind = "targetKind"
|
||||
TargetName = "targetName"
|
||||
Role = "role"
|
||||
CreateTime = "createTime"
|
||||
UpdateTime = "updateTime"
|
||||
StartTime = "startTime"
|
||||
LastScheduleTime = "lastScheduleTime"
|
||||
Annotation = "Annotation"
|
||||
Keyword = "keyword"
|
||||
UserFacing = "userfacing"
|
||||
Status = "status"
|
||||
Owner = "owner"
|
||||
|
||||
StatusRunning = "running"
|
||||
StatusPaused = "paused"
|
||||
StatusPending = "pending"
|
||||
StatusUpdating = "updating"
|
||||
StatusStopped = "stopped"
|
||||
StatusFailed = "failed"
|
||||
StatusBound = "bound"
|
||||
StatusLost = "lost"
|
||||
StatusComplete = "completed"
|
||||
StatusWarning = "warning"
|
||||
StatusUnschedulable = "unschedulable"
|
||||
Deployments = "deployments"
|
||||
DaemonSets = "daemonsets"
|
||||
Roles = "roles"
|
||||
Workspaces = "workspaces"
|
||||
WorkspaceRoles = "workspaceroles"
|
||||
CronJobs = "cronjobs"
|
||||
ConfigMaps = "configmaps"
|
||||
Ingresses = "ingresses"
|
||||
Jobs = "jobs"
|
||||
PersistentVolumeClaims = "persistentvolumeclaims"
|
||||
Pods = "pods"
|
||||
Secrets = "secrets"
|
||||
Services = "services"
|
||||
StatefulSets = "statefulsets"
|
||||
HorizontalPodAutoscalers = "horizontalpodautoscalers"
|
||||
Applications = "applications"
|
||||
Nodes = "nodes"
|
||||
Namespaces = "namespaces"
|
||||
StorageClasses = "storageclasses"
|
||||
ClusterRoles = "clusterroles"
|
||||
S2iBuilderTemplates = "s2ibuildertemplates"
|
||||
S2iBuilders = "s2ibuilders"
|
||||
S2iRuns = "s2iruns"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Get(namespace, name string) (interface{}, error)
|
||||
Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error)
|
||||
}
|
||||
|
||||
func ObjectMetaExactlyMath(key, value string, item metav1.ObjectMeta) bool {
|
||||
switch key {
|
||||
case Name:
|
||||
names := strings.Split(value, ",")
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case Keyword:
|
||||
if !strings.Contains(item.Name, value) && !FuzzyMatch(item.Labels, "", value) && !FuzzyMatch(item.Annotations, "", value) {
|
||||
return false
|
||||
}
|
||||
case Owner:
|
||||
for _, ownerReference := range item.OwnerReferences {
|
||||
if strings.Compare(string(ownerReference.UID), value) == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[key]; !ok || val != value {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ObjectMetaFuzzyMath(key, value string, item metav1.ObjectMeta) bool {
|
||||
switch key {
|
||||
case Name:
|
||||
if !strings.Contains(item.Name, value) && !strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], value) {
|
||||
return false
|
||||
}
|
||||
case Label:
|
||||
if !FuzzyMatch(item.Labels, "", value) {
|
||||
return false
|
||||
}
|
||||
case Annotation:
|
||||
if !FuzzyMatch(item.Annotations, "", value) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case App:
|
||||
if !strings.Contains(item.Labels[Chart], value) && !strings.Contains(item.Labels[Release], value) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !FuzzyMatch(item.Labels, key, value) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func FuzzyMatch(m map[string]string, key, value string) bool {
|
||||
|
||||
val, exist := m[key]
|
||||
|
||||
if value == "" && (!exist || val == "") {
|
||||
return true
|
||||
} else if value != "" && strings.Contains(val, value) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ObjectMetaCompare(left, right metav1.ObjectMeta, compareField string) bool {
|
||||
switch compareField {
|
||||
case CreateTime:
|
||||
if left.CreationTimestamp.Time.Equal(right.CreationTimestamp.Time) {
|
||||
if left.Namespace == right.Namespace {
|
||||
return strings.Compare(left.Name, right.Name) < 0
|
||||
}
|
||||
return strings.Compare(left.Namespace, right.Namespace) < 0
|
||||
}
|
||||
return left.CreationTimestamp.Time.Before(right.CreationTimestamp.Time)
|
||||
case Name:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Compare(left.Name, right.Name) <= 0
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package job
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
const (
|
||||
includeCronJob = "includeCronJob"
|
||||
cronJobKind = "CronJob"
|
||||
s2iRunKind = "S2iRun"
|
||||
includeS2iRun = "includeS2iRun"
|
||||
)
|
||||
|
||||
type jobSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewJobSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &jobSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *jobSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Batch().V1().Jobs().Lister().Jobs(namespace).Get(name)
|
||||
}
|
||||
|
||||
func jobStatus(item *batchv1.Job) string {
|
||||
status := v1alpha2.StatusFailed
|
||||
if item.Status.Active > 0 {
|
||||
status = v1alpha2.StatusRunning
|
||||
} else if item.Status.Failed > 0 {
|
||||
status = v1alpha2.StatusFailed
|
||||
} else if item.Status.Succeeded > 0 {
|
||||
status = v1alpha2.StatusComplete
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
||||
func (*jobSearcher) match(match map[string]string, item *batchv1.Job) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
if jobStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
case includeCronJob:
|
||||
if v == "false" && k8sutil.IsControlledBy(item.OwnerReferences, cronJobKind, "") {
|
||||
return false
|
||||
}
|
||||
case includeS2iRun:
|
||||
if v == "false" && k8sutil.IsControlledBy(item.OwnerReferences, s2iRunKind, "") {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*jobSearcher) fuzzy(fuzzy map[string]string, item *batchv1.Job) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
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(left, right *batchv1.Job, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.UpdateTime:
|
||||
return jobUpdateTime(left).Before(jobUpdateTime(right))
|
||||
default:
|
||||
return v1alpha2.ObjectMetaCompare(left.ObjectMeta, right.ObjectMeta, orderBy)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *jobSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
jobs, err := s.informers.Batch().V1().Jobs().Lister().Jobs(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*batchv1.Job, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = jobs
|
||||
} else {
|
||||
for _, item := range jobs {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package namespace
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type namespaceSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNamespaceSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &namespaceSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *namespaceSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Namespaces().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (*namespaceSearcher) match(match map[string]string, item *v1.Namespace) bool {
|
||||
for k, v := range match {
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*namespaceSearcher) fuzzy(fuzzy map[string]string, item *v1.Namespace) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *namespaceSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
namespaces, err := s.informers.Core().V1().Namespaces().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Namespace, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = namespaces
|
||||
} else {
|
||||
for _, item := range namespaces {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
const (
|
||||
nodeConfigOK v1.NodeConditionType = "ConfigOK"
|
||||
nodeKubeletReady v1.NodeConditionType = "KubeletReady"
|
||||
)
|
||||
|
||||
type nodeSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNodeSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &nodeSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *nodeSearcher) Get(_, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Nodes().Lister().Get(name)
|
||||
}
|
||||
|
||||
func getNodeStatus(node *v1.Node) string {
|
||||
if node.Spec.Unschedulable {
|
||||
return v1alpha2.StatusUnschedulable
|
||||
}
|
||||
for _, condition := range node.Status.Conditions {
|
||||
if isUnhealthyStatus(condition) {
|
||||
return v1alpha2.StatusWarning
|
||||
}
|
||||
}
|
||||
|
||||
return v1alpha2.StatusRunning
|
||||
}
|
||||
|
||||
var expectedConditions = map[v1.NodeConditionType]v1.ConditionStatus{
|
||||
v1.NodeMemoryPressure: v1.ConditionFalse,
|
||||
v1.NodeDiskPressure: v1.ConditionFalse,
|
||||
v1.NodePIDPressure: v1.ConditionFalse,
|
||||
v1.NodeNetworkUnavailable: v1.ConditionFalse,
|
||||
nodeConfigOK: v1.ConditionTrue,
|
||||
nodeKubeletReady: v1.ConditionTrue,
|
||||
v1.NodeReady: v1.ConditionTrue,
|
||||
}
|
||||
|
||||
func isUnhealthyStatus(condition v1.NodeCondition) bool {
|
||||
expectedStatus := expectedConditions[condition.Type]
|
||||
if expectedStatus != "" && condition.Status != expectedStatus {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (*nodeSearcher) match(match map[string]string, item *v1.Node) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Role:
|
||||
labelKey := fmt.Sprintf("node-role.kubernetes.io/%s", v)
|
||||
if _, ok := item.Labels[labelKey]; !ok {
|
||||
return false
|
||||
}
|
||||
case v1alpha2.Status:
|
||||
if getNodeStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*nodeSearcher) fuzzy(fuzzy map[string]string, item *v1.Node) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *nodeSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
nodes, err := s.informers.Core().V1().Nodes().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Node, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = nodes
|
||||
} else {
|
||||
for _, item := range nodes {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package persistentvolumeclaim
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
snapshotinformer "github.com/kubernetes-csi/external-snapshotter/client/v4/informers/externalversions"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
const (
|
||||
storageClassName = "storageClassName"
|
||||
)
|
||||
|
||||
type persistentVolumeClaimSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
snapshotInformers snapshotinformer.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewPersistentVolumeClaimSearcher(informers informers.SharedInformerFactory, snapshotInformer snapshotinformer.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &persistentVolumeClaimSearcher{
|
||||
informers: informers,
|
||||
snapshotInformers: snapshotInformer,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *persistentVolumeClaimSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().PersistentVolumeClaims().Lister().PersistentVolumeClaims(namespace).Get(name)
|
||||
}
|
||||
|
||||
func pvcStatus(item *v1.PersistentVolumeClaim) string {
|
||||
status := v1alpha2.StatusPending
|
||||
if item.Status.Phase == v1.ClaimPending {
|
||||
status = v1alpha2.StatusPending
|
||||
} else if item.Status.Phase == v1.ClaimBound {
|
||||
status = v1alpha2.StatusBound
|
||||
} else if item.Status.Phase == v1.ClaimLost {
|
||||
status = v1alpha2.StatusLost
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
||||
func (*persistentVolumeClaimSearcher) match(match map[string]string, item *v1.PersistentVolumeClaim) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
statuses := strings.Split(v, "|")
|
||||
if !sliceutil.HasString(statuses, pvcStatus(item)) {
|
||||
return false
|
||||
}
|
||||
case storageClassName:
|
||||
if item.Spec.StorageClassName == nil || *item.Spec.StorageClassName != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*persistentVolumeClaimSearcher) fuzzy(fuzzy map[string]string, item *v1.PersistentVolumeClaim) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *persistentVolumeClaimSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
persistentVolumeClaims, err := s.informers.Core().V1().PersistentVolumeClaims().Lister().PersistentVolumeClaims(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.PersistentVolumeClaim, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = persistentVolumeClaims
|
||||
} else {
|
||||
for _, item := range persistentVolumeClaims {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
i = i.DeepCopy()
|
||||
inUse := s.countPods(i.Name, i.Namespace)
|
||||
isSnapshotAllow := s.isSnapshotAllowed(i.GetAnnotations()["volume.beta.kubernetes.io/storage-provisioner"])
|
||||
if i.Annotations == nil {
|
||||
i.Annotations = make(map[string]string)
|
||||
}
|
||||
i.Annotations["kubesphere.io/in-use"] = strconv.FormatBool(inUse)
|
||||
i.Annotations["kubesphere.io/allow-snapshot"] = strconv.FormatBool(isSnapshotAllow)
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (s *persistentVolumeClaimSearcher) countPods(name, namespace string) bool {
|
||||
pods, err := s.informers.Core().V1().Pods().Lister().Pods(namespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, pod := range pods {
|
||||
for _, pvc := range pod.Spec.Volumes {
|
||||
if pvc.PersistentVolumeClaim != nil && pvc.PersistentVolumeClaim.ClaimName == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *persistentVolumeClaimSearcher) isSnapshotAllowed(provisioner string) bool {
|
||||
if len(provisioner) == 0 {
|
||||
return false
|
||||
}
|
||||
volumeSnapshotClasses, err := s.snapshotInformers.Snapshot().V1beta1().VolumeSnapshotClasses().Lister().List(labels.Everything())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, volumeSnapshotClass := range volumeSnapshotClasses {
|
||||
if volumeSnapshotClass.Driver == provisioner {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
package persistentvolumeclaim
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
snapshot "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
|
||||
snapshotefakeclient "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned/fake"
|
||||
snapshotinformers "github.com/kubernetes-csi/external-snapshotter/client/v4/informers/externalversions"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
var (
|
||||
testStorageClassName = "sc1"
|
||||
)
|
||||
|
||||
var (
|
||||
pvc1 = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-1",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
"kubesphere.io/in-use": "false",
|
||||
"kubesphere.io/allow-snapshot": "false",
|
||||
},
|
||||
},
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
StorageClassName: &testStorageClassName,
|
||||
},
|
||||
Status: corev1.PersistentVolumeClaimStatus{
|
||||
Phase: corev1.ClaimPending,
|
||||
},
|
||||
}
|
||||
|
||||
pvc2 = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-2",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
"kubesphere.io/in-use": "false",
|
||||
"kubesphere.io/allow-snapshot": "false",
|
||||
},
|
||||
},
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
StorageClassName: &testStorageClassName,
|
||||
},
|
||||
Status: corev1.PersistentVolumeClaimStatus{
|
||||
Phase: corev1.ClaimLost,
|
||||
},
|
||||
}
|
||||
|
||||
pvc3 = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-3",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
"kubesphere.io/in-use": "true",
|
||||
"kubesphere.io/allow-snapshot": "false",
|
||||
},
|
||||
},
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
StorageClassName: &testStorageClassName,
|
||||
},
|
||||
Status: corev1.PersistentVolumeClaimStatus{
|
||||
Phase: corev1.ClaimBound,
|
||||
},
|
||||
}
|
||||
|
||||
pod1 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-1",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Volumes: []corev1.Volume{
|
||||
{
|
||||
Name: "data",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: pvc3.Name,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
vsc1 = &snapshot.VolumeSnapshotClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "VolumeSnapshotClass-1",
|
||||
Namespace: "default",
|
||||
},
|
||||
Driver: testStorageClassName,
|
||||
}
|
||||
|
||||
persistentVolumeClaims = []interface{}{pvc1, pvc2, pvc3}
|
||||
pods = []interface{}{pod1}
|
||||
volumeSnapshotClasses = []interface{}{vsc1}
|
||||
)
|
||||
|
||||
func prepare() (v1alpha2.Interface, error) {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
snapshotClient := snapshotefakeclient.NewSimpleClientset()
|
||||
snapshotInformers := snapshotinformers.NewSharedInformerFactory(snapshotClient, 0)
|
||||
|
||||
for _, persistentVolumeClaim := range persistentVolumeClaims {
|
||||
err := informer.Core().V1().PersistentVolumeClaims().Informer().GetIndexer().Add(persistentVolumeClaim)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, pod := range pods {
|
||||
err := informer.Core().V1().Pods().Informer().GetIndexer().Add(pod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, volumeSnapshotClass := range volumeSnapshotClasses {
|
||||
err := snapshotInformers.Snapshot().V1().VolumeSnapshotClasses().Informer().GetIndexer().Add(volumeSnapshotClass)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return NewPersistentVolumeClaimSearcher(informer, snapshotInformers), nil
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
tests := []struct {
|
||||
Namespace string
|
||||
Name string
|
||||
Expected interface{}
|
||||
ExpectedErr error
|
||||
}{
|
||||
{
|
||||
"default",
|
||||
"pvc-1",
|
||||
pvc1,
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter, err := prepare()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := getter.Get(test.Namespace, test.Name)
|
||||
if test.ExpectedErr != nil && err != test.ExpectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
diff := cmp.Diff(got, test.Expected)
|
||||
if diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.Expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSearch(t *testing.T) {
|
||||
tests := []struct {
|
||||
Namespace string
|
||||
Conditions *params.Conditions
|
||||
OrderBy string
|
||||
Reverse bool
|
||||
Expected []interface{}
|
||||
ExpectedErr error
|
||||
}{
|
||||
{
|
||||
Namespace: "default",
|
||||
Conditions: ¶ms.Conditions{
|
||||
Match: map[string]string{
|
||||
v1alpha2.Status: v1alpha2.StatusPending,
|
||||
},
|
||||
Fuzzy: nil,
|
||||
},
|
||||
OrderBy: "name",
|
||||
Reverse: false,
|
||||
Expected: []interface{}{pvc1},
|
||||
ExpectedErr: nil,
|
||||
},
|
||||
{
|
||||
Namespace: "default",
|
||||
Conditions: ¶ms.Conditions{
|
||||
Match: map[string]string{
|
||||
v1alpha2.Status: v1alpha2.StatusLost,
|
||||
},
|
||||
Fuzzy: nil,
|
||||
},
|
||||
OrderBy: "name",
|
||||
Reverse: false,
|
||||
Expected: []interface{}{pvc2},
|
||||
ExpectedErr: nil,
|
||||
},
|
||||
{
|
||||
Namespace: "default",
|
||||
Conditions: ¶ms.Conditions{
|
||||
Match: map[string]string{
|
||||
v1alpha2.Status: v1alpha2.StatusBound,
|
||||
},
|
||||
Fuzzy: nil,
|
||||
},
|
||||
OrderBy: "name",
|
||||
Reverse: false,
|
||||
Expected: []interface{}{pvc3},
|
||||
ExpectedErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
searcher, err := prepare()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := searcher.Search(test.Namespace, test.Conditions, test.OrderBy, test.Reverse)
|
||||
if test.ExpectedErr != nil && err != test.ExpectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.Expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.Expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package pod
|
||||
|
||||
import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type podSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewPodSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &podSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *podSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Pods().Lister().Pods(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (s *podSearcher) podBelongTo(item *v1.Pod, kind string, name string) bool {
|
||||
switch kind {
|
||||
case "Deployment":
|
||||
if s.podBelongToDeployment(item, name) {
|
||||
return true
|
||||
}
|
||||
case "ReplicaSet":
|
||||
if podBelongToReplicaSet(item, name) {
|
||||
return true
|
||||
}
|
||||
case "DaemonSet":
|
||||
if podBelongToDaemonSet(item, name) {
|
||||
return true
|
||||
}
|
||||
case "StatefulSet":
|
||||
if podBelongToStatefulSet(item, name) {
|
||||
return true
|
||||
}
|
||||
case "Job":
|
||||
if podBelongToJob(item, name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func replicaSetBelongToDeployment(replicaSet *appsv1.ReplicaSet, deploymentName string) bool {
|
||||
for _, owner := range replicaSet.OwnerReferences {
|
||||
if owner.Kind == "Deployment" && owner.Name == deploymentName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func podBelongToDaemonSet(item *v1.Pod, name string) bool {
|
||||
for _, owner := range item.OwnerReferences {
|
||||
if owner.Kind == "DaemonSet" && owner.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func podBelongToJob(item *v1.Pod, name string) bool {
|
||||
for _, owner := range item.OwnerReferences {
|
||||
if owner.Kind == "Job" && owner.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func podBelongToReplicaSet(item *v1.Pod, replicaSetName string) bool {
|
||||
for _, owner := range item.OwnerReferences {
|
||||
if owner.Kind == "ReplicaSet" && owner.Name == replicaSetName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func podBelongToStatefulSet(item *v1.Pod, statefulSetName string) bool {
|
||||
for _, owner := range item.OwnerReferences {
|
||||
if owner.Kind == "StatefulSet" && owner.Name == statefulSetName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *podSearcher) podBelongToDeployment(item *v1.Pod, deploymentName string) bool {
|
||||
replicas, err := s.informers.Apps().V1().ReplicaSets().Lister().ReplicaSets(item.Namespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, r := range replicas {
|
||||
if replicaSetBelongToDeployment(r, deploymentName) && podBelongToReplicaSet(item, r.Name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func podBindPVC(item *v1.Pod, pvcName string) bool {
|
||||
for _, v := range item.Spec.Volumes {
|
||||
if v.VolumeSource.PersistentVolumeClaim != nil &&
|
||||
v.VolumeSource.PersistentVolumeClaim.ClaimName == pvcName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *podSearcher) podBelongToService(item *v1.Pod, serviceName string) bool {
|
||||
service, err := s.informers.Core().V1().Services().Lister().Services(item.Namespace).Get(serviceName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
|
||||
if selector.Empty() || !selector.Matches(labels.Set(item.Labels)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *podSearcher) match(match map[string]string, item *v1.Pod) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.OwnerKind:
|
||||
fallthrough
|
||||
case v1alpha2.OwnerName:
|
||||
kind := match[v1alpha2.OwnerKind]
|
||||
name := match[v1alpha2.OwnerName]
|
||||
if !s.podBelongTo(item, kind, name) {
|
||||
return false
|
||||
}
|
||||
case "nodeName":
|
||||
if item.Spec.NodeName != v {
|
||||
return false
|
||||
}
|
||||
case "pvcName":
|
||||
if !podBindPVC(item, v) {
|
||||
return false
|
||||
}
|
||||
case "serviceName":
|
||||
if !s.podBelongToService(item, v) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*podSearcher) fuzzy(fuzzy map[string]string, item *v1.Pod) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*podSearcher) compare(left, right *v1.Pod, orderBy string) bool {
|
||||
switch orderBy {
|
||||
case v1alpha2.StartTime:
|
||||
if left.Status.StartTime == nil {
|
||||
return false
|
||||
}
|
||||
if right.Status.StartTime == nil {
|
||||
return true
|
||||
}
|
||||
return left.Status.StartTime.Before(right.Status.StartTime)
|
||||
default:
|
||||
return v1alpha2.ObjectMetaCompare(left.ObjectMeta, right.ObjectMeta, orderBy)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *podSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
|
||||
pods, err := s.informers.Core().V1().Pods().Lister().Pods(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Pod, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = pods
|
||||
} else {
|
||||
for _, item := range pods {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return s.compare(result[i], result[j], orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
fakesnapshot "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned/fake"
|
||||
fakeistio "istio.io/client-go/pkg/clientset/versioned/fake"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
fakek8s "k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
func TestConditions(t *testing.T) {
|
||||
factory, err := prepare()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resource := NewResourceGetter(factory)
|
||||
|
||||
tests := []struct {
|
||||
Name string
|
||||
Namespace string
|
||||
Resource string
|
||||
Conditions *params.Conditions
|
||||
OrderBy string
|
||||
Reverse bool
|
||||
Limit int
|
||||
Offset int
|
||||
ExpectResponse *models.PageableResponse
|
||||
ExpectError error
|
||||
}{{
|
||||
Name: "list namespace order by name asc",
|
||||
Namespace: "",
|
||||
Resource: "namespaces",
|
||||
Conditions: ¶ms.Conditions{},
|
||||
OrderBy: "name",
|
||||
Reverse: false,
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
ExpectResponse: &models.PageableResponse{
|
||||
Items: []interface{}{defaultNamespace, kubesphereNamespace},
|
||||
TotalCount: 2,
|
||||
},
|
||||
ExpectError: nil,
|
||||
}, {
|
||||
Name: "list namespace order by name desc",
|
||||
Namespace: "",
|
||||
Resource: "namespaces",
|
||||
Conditions: ¶ms.Conditions{},
|
||||
OrderBy: "name",
|
||||
Reverse: true,
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
ExpectResponse: &models.PageableResponse{
|
||||
Items: []interface{}{kubesphereNamespace, defaultNamespace},
|
||||
TotalCount: 2,
|
||||
},
|
||||
ExpectError: nil,
|
||||
},
|
||||
{
|
||||
Name: "list deployment",
|
||||
Namespace: "default",
|
||||
Resource: "deployments",
|
||||
Conditions: ¶ms.Conditions{},
|
||||
OrderBy: "name",
|
||||
Reverse: false,
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
ExpectResponse: &models.PageableResponse{
|
||||
Items: []interface{}{nginxDeployment, redisDeployment},
|
||||
TotalCount: 2,
|
||||
},
|
||||
ExpectError: nil,
|
||||
},
|
||||
{
|
||||
Name: "filter deployment by keyword",
|
||||
Namespace: "default",
|
||||
Resource: "deployments",
|
||||
Conditions: ¶ms.Conditions{
|
||||
Match: map[string]string{v1alpha2.Keyword: "ngin"},
|
||||
Fuzzy: nil,
|
||||
},
|
||||
OrderBy: "name",
|
||||
Reverse: true,
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
ExpectResponse: &models.PageableResponse{
|
||||
Items: []interface{}{nginxDeployment},
|
||||
TotalCount: 1,
|
||||
},
|
||||
ExpectError: nil,
|
||||
},
|
||||
{
|
||||
Name: "filter deployment by label",
|
||||
Namespace: "default",
|
||||
Resource: "deployments",
|
||||
Conditions: ¶ms.Conditions{
|
||||
Match: map[string]string{"kubesphere.io/creator": "admin"},
|
||||
Fuzzy: nil,
|
||||
},
|
||||
OrderBy: "",
|
||||
Reverse: true,
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
ExpectResponse: &models.PageableResponse{
|
||||
Items: []interface{}{redisDeployment},
|
||||
TotalCount: 1,
|
||||
},
|
||||
ExpectError: nil,
|
||||
}, {
|
||||
Name: "filter deployment by status",
|
||||
Namespace: "default",
|
||||
Resource: "deployments",
|
||||
Conditions: ¶ms.Conditions{
|
||||
Match: map[string]string{v1alpha2.Status: v1alpha2.StatusRunning},
|
||||
Fuzzy: nil,
|
||||
},
|
||||
OrderBy: "",
|
||||
Reverse: true,
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
ExpectResponse: &models.PageableResponse{
|
||||
Items: []interface{}{nginxDeployment},
|
||||
TotalCount: 1,
|
||||
},
|
||||
ExpectError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
response, err := resource.ListResources(test.Namespace, test.Resource, test.Conditions, test.OrderBy, test.Reverse, test.Limit, test.Offset)
|
||||
if err != test.ExpectError {
|
||||
t.Fatalf("expected error: %s, got: %s", test.ExpectError, err)
|
||||
}
|
||||
if diff := cmp.Diff(test.ExpectResponse, response); diff != "" {
|
||||
t.Errorf(diff)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
defaultNamespace = &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default",
|
||||
Labels: map[string]string{"kubesphere.io/workspace": "system-workspace"},
|
||||
},
|
||||
}
|
||||
kubesphereNamespace = &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kubesphere-system",
|
||||
Labels: map[string]string{"kubesphere.io/workspace": "system-workspace"},
|
||||
},
|
||||
}
|
||||
|
||||
replicas = int32(1)
|
||||
|
||||
nginxDeployment = &appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "nginx",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
},
|
||||
Status: appsv1.DeploymentStatus{
|
||||
ReadyReplicas: 1,
|
||||
},
|
||||
}
|
||||
redisDeployment = &appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "redis",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{"kubesphere.io/creator": "admin"},
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
},
|
||||
Status: appsv1.DeploymentStatus{
|
||||
ReadyReplicas: 0,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func prepare() (informers.InformerFactory, error) {
|
||||
|
||||
namespaces := []interface{}{defaultNamespace, kubesphereNamespace}
|
||||
deployments := []interface{}{nginxDeployment, redisDeployment}
|
||||
|
||||
ksClient := fakeks.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
istioClient := fakeistio.NewSimpleClientset()
|
||||
snapshotClient := fakesnapshot.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, nil, nil)
|
||||
|
||||
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
|
||||
|
||||
for _, namespace := range namespaces {
|
||||
err := k8sInformerFactory.Core().V1().Namespaces().Informer().GetIndexer().Add(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, deployment := range deployments {
|
||||
err := k8sInformerFactory.Apps().V1().Deployments().Informer().GetIndexer().Add(deployment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return fakeInformerFactory, nil
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/clusterrole"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/configmap"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/cronjob"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/daemonset"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/deployment"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/hpa"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/ingress"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/job"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/namespace"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/node"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/persistentvolumeclaim"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/pod"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/role"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/s2buildertemplate"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/s2ibuilder"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/s2irun"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/secret"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/service"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/statefulset"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/storageclass"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/workspace"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
)
|
||||
|
||||
var ErrResourceNotSupported = errors.New("resource is not supported")
|
||||
|
||||
type ResourceGetter struct {
|
||||
resourcesGetters map[string]v1alpha2.Interface
|
||||
}
|
||||
|
||||
func (r ResourceGetter) Add(resource string, getter v1alpha2.Interface) {
|
||||
if r.resourcesGetters == nil {
|
||||
r.resourcesGetters = make(map[string]v1alpha2.Interface)
|
||||
}
|
||||
r.resourcesGetters[resource] = getter
|
||||
}
|
||||
|
||||
func NewResourceGetter(factory informers.InformerFactory) *ResourceGetter {
|
||||
resourceGetters := make(map[string]v1alpha2.Interface)
|
||||
|
||||
resourceGetters[v1alpha2.ConfigMaps] = configmap.NewConfigmapSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.CronJobs] = cronjob.NewCronJobSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.DaemonSets] = daemonset.NewDaemonSetSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Deployments] = deployment.NewDeploymentSetSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Ingresses] = ingress.NewIngressSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Jobs] = job.NewJobSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.PersistentVolumeClaims] = persistentvolumeclaim.NewPersistentVolumeClaimSearcher(factory.KubernetesSharedInformerFactory(), factory.SnapshotSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Secrets] = secret.NewSecretSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Services] = service.NewServiceSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.StatefulSets] = statefulset.NewStatefulSetSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Pods] = pod.NewPodSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Roles] = role.NewRoleSearcher(factory.KubernetesSharedInformerFactory())
|
||||
|
||||
resourceGetters[v1alpha2.Nodes] = node.NewNodeSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Namespaces] = namespace.NewNamespaceSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.ClusterRoles] = clusterrole.NewClusterRoleSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.StorageClasses] = storageclass.NewStorageClassesSearcher(factory.KubernetesSharedInformerFactory(), factory.SnapshotSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.HorizontalPodAutoscalers] = hpa.NewHpaSearcher(factory.KubernetesSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.S2iBuilders] = s2ibuilder.NewS2iBuilderSearcher(factory.KubeSphereSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.S2iRuns] = s2irun.NewS2iRunSearcher(factory.KubeSphereSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.S2iBuilderTemplates] = s2buildertemplate.NewS2iBuidlerTemplateSearcher(factory.KubeSphereSharedInformerFactory())
|
||||
resourceGetters[v1alpha2.Workspaces] = workspace.NewWorkspaceSearcher(factory.KubeSphereSharedInformerFactory())
|
||||
|
||||
return &ResourceGetter{resourcesGetters: resourceGetters}
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
clusterResources = []string{v1alpha2.Nodes, v1alpha2.Workspaces, v1alpha2.Namespaces, v1alpha2.ClusterRoles, v1alpha2.StorageClasses, v1alpha2.S2iBuilderTemplates}
|
||||
)
|
||||
|
||||
func (r *ResourceGetter) GetResource(namespace, resource, name string) (interface{}, error) {
|
||||
// none namespace resource
|
||||
if namespace != "" && sliceutil.HasString(clusterResources, resource) {
|
||||
return nil, ErrResourceNotSupported
|
||||
}
|
||||
if searcher, ok := r.resourcesGetters[resource]; ok {
|
||||
resource, err := searcher.Get(namespace, name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return resource, nil
|
||||
}
|
||||
return nil, ErrResourceNotSupported
|
||||
}
|
||||
|
||||
func (r *ResourceGetter) ListResources(namespace, resource string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
|
||||
var items []interface{}
|
||||
var err error
|
||||
var result []interface{}
|
||||
|
||||
// none namespace resource
|
||||
if namespace != "" && sliceutil.HasString(clusterResources, resource) {
|
||||
return nil, ErrResourceNotSupported
|
||||
}
|
||||
|
||||
if searcher, ok := r.resourcesGetters[resource]; ok {
|
||||
result, err = searcher.Search(namespace, conditions, orderBy, reverse)
|
||||
} else {
|
||||
return nil, ErrResourceNotSupported
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if limit == -1 || limit+offset > len(result) {
|
||||
limit = len(result) - offset
|
||||
}
|
||||
|
||||
items = result[offset : offset+limit]
|
||||
|
||||
return &models.PageableResponse{TotalCount: len(result), Items: items}, nil
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package role
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type roleSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewRoleSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &roleSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *roleSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Rbac().V1().Roles().Lister().Roles(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (*roleSearcher) match(match map[string]string, item *rbac.Role) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.UserFacing:
|
||||
if v == "true" {
|
||||
if !isUserFacingRole(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*roleSearcher) fuzzy(fuzzy map[string]string, item *rbac.Role) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *roleSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
roles, err := s.informers.Rbac().V1().Roles().Lister().Roles(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*rbac.Role, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = roles
|
||||
} else {
|
||||
for _, item := range roles {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// role created by user from kubesphere dashboard
|
||||
func isUserFacingRole(role *rbac.Role) bool {
|
||||
return role.Annotations[constants.CreatorAnnotationKey] != ""
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package s2buildertemplate
|
||||
|
||||
import (
|
||||
"kubesphere.io/api/devops/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type s2iBuilderTemplateSearcher struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewS2iBuidlerTemplateSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &s2iBuilderTemplateSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *s2iBuilderTemplateSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Devops().V1alpha1().S2iBuilderTemplates().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (*s2iBuilderTemplateSearcher) match(match map[string]string, item *v1alpha1.S2iBuilderTemplate) bool {
|
||||
for k, v := range match {
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*s2iBuilderTemplateSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iBuilderTemplate) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *s2iBuilderTemplateSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
builderTemplates, err := s.informers.Devops().V1alpha1().S2iBuilderTemplates().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1alpha1.S2iBuilderTemplate, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = builderTemplates
|
||||
} else {
|
||||
for _, item := range builderTemplates {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package s2ibuilder
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/api/devops/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type s2iBuilderSearcher struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewS2iBuilderSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &s2iBuilderSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *s2iBuilderSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Devops().V1alpha1().S2iBuilders().Lister().S2iBuilders(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (*s2iBuilderSearcher) match(match map[string]string, item *v1alpha1.S2iBuilder) bool {
|
||||
for k, v := range match {
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*s2iBuilderSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iBuilder) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *s2iBuilderSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
s2iBuilders, err := s.informers.Devops().V1alpha1().S2iBuilders().Lister().S2iBuilders(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1alpha1.S2iBuilder, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = s2iBuilders
|
||||
} else {
|
||||
for _, item := range s2iBuilders {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package s2irun
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/api/devops/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type s2iRunSearcher struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewS2iRunSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &s2iRunSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *s2iRunSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Devops().V1alpha1().S2iRuns().Lister().S2iRuns(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (*s2iRunSearcher) match(match map[string]string, item *v1alpha1.S2iRun) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
if string(item.Status.RunState) != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*s2iRunSearcher) fuzzy(fuzzy map[string]string, item *v1alpha1.S2iRun) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *s2iRunSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
s2iRuns, err := s.informers.Devops().V1alpha1().S2iRuns().Lister().S2iRuns(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1alpha1.S2iRun, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = s2iRuns
|
||||
} else {
|
||||
for _, item := range s2iRuns {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package secret
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type secretSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewSecretSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &secretSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *secretSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Secrets().Lister().Secrets(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (*secretSearcher) match(match map[string]string, item *v1.Secret) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case "type":
|
||||
if string(item.Type) != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*secretSearcher) fuzzy(fuzzy map[string]string, item *v1.Secret) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *secretSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
secrets, err := s.informers.Core().V1().Secrets().Lister().Secrets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Secret, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = secrets
|
||||
} else {
|
||||
for _, item := range secrets {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type serviceSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewServiceSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &serviceSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *serviceSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Core().V1().Services().Lister().Services(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (*serviceSearcher) match(match map[string]string, item *v1.Service) bool {
|
||||
for k, v := range match {
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*serviceSearcher) fuzzy(fuzzy map[string]string, item *v1.Service) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *serviceSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
services, err := s.informers.Core().V1().Services().Lister().Services(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.Service, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = services
|
||||
} else {
|
||||
for _, item := range services {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package statefulset
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type statefulSetSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewStatefulSetSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &statefulSetSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *statefulSetSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Apps().V1().StatefulSets().Lister().StatefulSets(namespace).Get(name)
|
||||
}
|
||||
|
||||
func statefulSetStatus(item *v1.StatefulSet) string {
|
||||
if item.Spec.Replicas != nil {
|
||||
if item.Status.ReadyReplicas == 0 && *item.Spec.Replicas == 0 {
|
||||
return v1alpha2.StatusStopped
|
||||
} else if item.Status.ReadyReplicas == *item.Spec.Replicas {
|
||||
return v1alpha2.StatusRunning
|
||||
} else {
|
||||
return v1alpha2.StatusUpdating
|
||||
}
|
||||
}
|
||||
return v1alpha2.StatusStopped
|
||||
}
|
||||
|
||||
func (*statefulSetSearcher) match(match map[string]string, item *v1.StatefulSet) bool {
|
||||
for k, v := range match {
|
||||
switch k {
|
||||
case v1alpha2.Status:
|
||||
if statefulSetStatus(item) != v {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*statefulSetSearcher) fuzzy(fuzzy map[string]string, item *v1.StatefulSet) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *statefulSetSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
statefulSets, err := s.informers.Apps().V1().StatefulSets().Lister().StatefulSets(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.StatefulSet, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = statefulSets
|
||||
} else {
|
||||
for _, item := range statefulSets {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package storageclass
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
snapshotinformer "github.com/kubernetes-csi/external-snapshotter/client/v4/informers/externalversions"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type storageClassesSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
snapshotInformers snapshotinformer.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewStorageClassesSearcher(informers informers.SharedInformerFactory, snapshotInformer snapshotinformer.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &storageClassesSearcher{
|
||||
informers: informers,
|
||||
snapshotInformers: snapshotInformer,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *storageClassesSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Storage().V1().StorageClasses().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (*storageClassesSearcher) match(match map[string]string, item *v1.StorageClass) bool {
|
||||
for k, v := range match {
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*storageClassesSearcher) fuzzy(fuzzy map[string]string, item *v1.StorageClass) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *storageClassesSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
storageClasses, err := s.informers.Storage().V1().StorageClasses().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*v1.StorageClass, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = storageClasses
|
||||
} else {
|
||||
for _, item := range storageClasses {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
i = i.DeepCopy()
|
||||
count := s.countPersistentVolumeClaims(i.Name)
|
||||
if i.Annotations == nil {
|
||||
i.Annotations = make(map[string]string)
|
||||
}
|
||||
i.Annotations["kubesphere.io/pvc-count"] = strconv.Itoa(count)
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (s *storageClassesSearcher) countPersistentVolumeClaims(name string) int {
|
||||
pvcs, err := s.informers.Core().V1().PersistentVolumeClaims().Lister().List(labels.Everything())
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
var count int
|
||||
|
||||
for _, pvc := range pvcs {
|
||||
if (pvc.Spec.StorageClassName != nil && *pvc.Spec.StorageClassName == name) || (pvc.Annotations != nil && pvc.Annotations[corev1.BetaStorageClassAnnotation] == name) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
// Copyright 2022 The KubeSphere Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package storageclass
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/storage/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
var (
|
||||
sc1 = &v1.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "sc1",
|
||||
},
|
||||
}
|
||||
|
||||
sc1Expected = &v1.StorageClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "sc1",
|
||||
Annotations: map[string]string{
|
||||
"kubesphere.io/pvc-count": "1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
scs = []interface{}{sc1}
|
||||
|
||||
scsExpected = []interface{}{sc1Expected}
|
||||
|
||||
pvc1 = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc1",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
VolumeName: "pvc1-volume",
|
||||
StorageClassName: pointer.StringPtr("sc1"),
|
||||
},
|
||||
}
|
||||
|
||||
pvc2 = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc2",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
VolumeName: "pvc2-volume",
|
||||
},
|
||||
}
|
||||
|
||||
pvcs = []interface{}{pvc1, pvc2}
|
||||
)
|
||||
|
||||
func prepare() (v1alpha2.Interface, error) {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, sc := range scs {
|
||||
err := informer.Storage().V1().StorageClasses().Informer().GetIndexer().Add(sc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, pvc := range pvcs {
|
||||
err := informer.Core().V1().PersistentVolumeClaims().Informer().GetIndexer().Add(pvc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return NewStorageClassesSearcher(informer, nil), nil
|
||||
}
|
||||
|
||||
func TestSearch(t *testing.T) {
|
||||
tests := []struct {
|
||||
namespace string
|
||||
name string
|
||||
conditions *params.Conditions
|
||||
orderBy string
|
||||
reverse bool
|
||||
expected interface{}
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
namespace: "default",
|
||||
name: sc1.Name,
|
||||
conditions: ¶ms.Conditions{},
|
||||
orderBy: "name",
|
||||
reverse: true,
|
||||
expected: scsExpected,
|
||||
expectedErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
searcher, err := prepare()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := searcher.Search(test.namespace, test.conditions, test.orderBy, test.reverse)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package workspace
|
||||
|
||||
import (
|
||||
tenantv1alpha1 "kubesphere.io/api/tenant/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
|
||||
"sort"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
)
|
||||
|
||||
type workspaceSearcher struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewWorkspaceSearcher(informers externalversions.SharedInformerFactory) v1alpha2.Interface {
|
||||
return &workspaceSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *workspaceSearcher) Get(namespace, name string) (interface{}, error) {
|
||||
return s.informers.Tenant().V1alpha1().Workspaces().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (*workspaceSearcher) match(match map[string]string, item *tenantv1alpha1.Workspace) bool {
|
||||
for k, v := range match {
|
||||
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*workspaceSearcher) fuzzy(fuzzy map[string]string, item *tenantv1alpha1.Workspace) bool {
|
||||
for k, v := range fuzzy {
|
||||
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *workspaceSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
|
||||
|
||||
workspaces, err := s.informers.Tenant().V1alpha1().Workspaces().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*tenantv1alpha1.Workspace, 0)
|
||||
|
||||
if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
|
||||
result = workspaces
|
||||
} else {
|
||||
for _, item := range workspaces {
|
||||
if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
if reverse {
|
||||
i, j = j, i
|
||||
}
|
||||
return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
|
||||
})
|
||||
|
||||
r := make([]interface{}, 0)
|
||||
for _, i := range result {
|
||||
r = append(r, i)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
appv1beta1 "sigs.k8s.io/application/api/v1beta1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type applicationsGetter struct {
|
||||
c cache.Cache
|
||||
}
|
||||
|
||||
func New(c cache.Cache) v1alpha3.Interface {
|
||||
return &applicationsGetter{c}
|
||||
}
|
||||
|
||||
func (d *applicationsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
app := appv1beta1.Application{}
|
||||
err := d.c.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, &app)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return &app, nil
|
||||
}
|
||||
|
||||
func (d *applicationsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
applications := appv1beta1.ApplicationList{}
|
||||
err := d.c.List(context.Background(), &applications, &client.ListOptions{Namespace: namespace, LabelSelector: query.Selector()})
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
for i := range applications.Items {
|
||||
result = append(result, &applications.Items[i])
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *applicationsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftApplication, ok := left.(*appv1beta1.Application)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightApplication, ok := right.(*appv1beta1.Application)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch field {
|
||||
case query.FieldUpdateTime:
|
||||
fallthrough
|
||||
case query.FieldLastUpdateTimestamp:
|
||||
return lastUpdateTime(leftApplication).After(lastUpdateTime(rightApplication))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftApplication.ObjectMeta, rightApplication.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *applicationsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
application, ok := object.(*appv1beta1.Application)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(application.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func lastUpdateTime(application *appv1beta1.Application) time.Time {
|
||||
lut := application.CreationTimestamp.Time
|
||||
for _, condition := range application.Status.Conditions {
|
||||
if condition.LastUpdateTime.After(lut) {
|
||||
lut = condition.LastUpdateTime.Time
|
||||
}
|
||||
}
|
||||
return lut
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
core "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/klog/v2"
|
||||
appv1beta1 "sigs.k8s.io/application/api/v1beta1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
)
|
||||
|
||||
var c client.Client
|
||||
|
||||
func createNamespace(name string, ctx context.Context) {
|
||||
namespace := &core.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
}
|
||||
err := c.Create(ctx, namespace)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func compare(actual *appv1beta1.Application, expects ...*appv1beta1.Application) bool {
|
||||
for _, app := range expects {
|
||||
if actual.Name == app.Name && actual.Namespace == app.Namespace && reflect.DeepEqual(actual.Labels, app.Labels) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestGetListApplications(t *testing.T) {
|
||||
e := &envtest.Environment{CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "..", "config", "ks-core", "crds")}}
|
||||
cfg, err := e.Start()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
sch := scheme.Scheme
|
||||
if err := appv1beta1.AddToScheme(sch); err != nil {
|
||||
t.Fatalf("unable add APIs to scheme: %v", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
ce, _ := cache.New(cfg, cache.Options{Scheme: sch})
|
||||
go ce.Start(ctx)
|
||||
ce.WaitForCacheSync(ctx)
|
||||
|
||||
c, _ = client.New(cfg, client.Options{Scheme: sch})
|
||||
|
||||
var labelSet1 = map[string]string{"foo-1": "bar-1"}
|
||||
var labelSet2 = map[string]string{"foo-2": "bar-2"}
|
||||
|
||||
var ns = "ns-1"
|
||||
testCases := []*appv1beta1.Application{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app-1",
|
||||
Namespace: ns,
|
||||
Labels: labelSet1,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app-2",
|
||||
Namespace: ns,
|
||||
Labels: labelSet2,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// ctx := context.TODO()
|
||||
createNamespace(ns, ctx)
|
||||
|
||||
for _, app := range testCases {
|
||||
if err = c.Create(ctx, app); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
getter := New(ce)
|
||||
|
||||
results, err := getter.List(ns, &query.Query{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if results.TotalItems != len(testCases) {
|
||||
t.Fatal("TotalItems is not match")
|
||||
}
|
||||
|
||||
if len(results.Items) != len(testCases) {
|
||||
t.Fatal("Items numbers is not match mock data")
|
||||
}
|
||||
|
||||
for _, app := range results.Items {
|
||||
app, err := app.(*appv1beta1.Application)
|
||||
if !err {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !compare(app, testCases...) {
|
||||
t.Errorf("The results %v not match testcases %v", results.Items, testCases)
|
||||
}
|
||||
}
|
||||
|
||||
result, err := getter.Get(ns, "app-1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
app := result.(*appv1beta1.Application)
|
||||
if !compare(app, testCases...) {
|
||||
t.Errorf("The results %v not match testcases %v", result, testCases)
|
||||
}
|
||||
}
|
||||
@@ -1,72 +1,62 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type clustersGetter struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(informers externalversions.SharedInformerFactory) v1alpha3.Interface {
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &clustersGetter{
|
||||
informers: informers,
|
||||
cache: cache,
|
||||
}
|
||||
}
|
||||
|
||||
func (c clustersGetter) Get(_, name string) (runtime.Object, error) {
|
||||
cluster, err := c.informers.Cluster().V1alpha1().Clusters().Lister().Get(name)
|
||||
if err != nil {
|
||||
func (c *clustersGetter) Get(_, name string) (runtime.Object, error) {
|
||||
cluster := &clusterv1alpha1.Cluster{}
|
||||
if err := c.cache.Get(context.Background(), types.NamespacedName{Name: name}, cluster); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.transform(cluster), nil
|
||||
}
|
||||
|
||||
func (c clustersGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
clusters, err := c.informers.Cluster().V1alpha1().Clusters().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
func (c *clustersGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
cluster := &clusterv1alpha1.ClusterList{}
|
||||
if err := c.cache.List(context.Background(), cluster, client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, cluster := range clusters {
|
||||
result = append(result, cluster)
|
||||
for _, item := range cluster.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, c.compare, c.filter, c.transform), nil
|
||||
}
|
||||
|
||||
func (c clustersGetter) transform(obj runtime.Object) runtime.Object {
|
||||
func (c *clustersGetter) transform(obj runtime.Object) runtime.Object {
|
||||
in := obj.(*clusterv1alpha1.Cluster)
|
||||
out := in.DeepCopy()
|
||||
out.Spec.Connection.KubeConfig = nil
|
||||
return out
|
||||
}
|
||||
|
||||
func (c clustersGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
func (c *clustersGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftCluster, ok := left.(*clusterv1alpha1.Cluster)
|
||||
if !ok {
|
||||
return false
|
||||
@@ -80,7 +70,7 @@ func (c clustersGetter) compare(left runtime.Object, right runtime.Object, field
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftCluster.ObjectMeta, rightCluster.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (c clustersGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
func (c *clustersGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
cluster, ok := object.(*clusterv1alpha1.Cluster)
|
||||
if !ok {
|
||||
return false
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
)
|
||||
|
||||
var clusters = []*clusterv1alpha1.Cluster{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
"cluster.kubesphere.io/region": "beijing",
|
||||
"cluster.kubesphere.io/group": "development",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar",
|
||||
Labels: map[string]string{
|
||||
"cluster.kubesphere.io/region": "beijing",
|
||||
"cluster.kubesphere.io/group": "production",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "whatever",
|
||||
Labels: map[string]string{
|
||||
"cluster.kubesphere.io/region": "shanghai",
|
||||
"cluster.kubesphere.io/group": "testing",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func clustersToInterface(clusters ...*clusterv1alpha1.Cluster) []interface{} {
|
||||
items := make([]interface{}, 0)
|
||||
|
||||
for _, cluster := range clusters {
|
||||
items = append(items, cluster)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func clustersToRuntimeObject(clusters ...*clusterv1alpha1.Cluster) []runtime.Object {
|
||||
items := make([]runtime.Object, 0)
|
||||
|
||||
for _, cluster := range clusters {
|
||||
items = append(items, cluster)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func TestClustersGetter(t *testing.T) {
|
||||
var testCases = []struct {
|
||||
description string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
}{
|
||||
{
|
||||
description: "Test normal case",
|
||||
query: &query.Query{
|
||||
LabelSelector: "cluster.kubesphere.io/region=beijing",
|
||||
Ascending: false,
|
||||
},
|
||||
expected: &api.ListResult{
|
||||
TotalItems: 2,
|
||||
Items: clustersToInterface(clusters[0], clusters[1]),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
client := fake.NewSimpleClientset(clustersToRuntimeObject(clusters...)...)
|
||||
informer := externalversions.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, cluster := range clusters {
|
||||
informer.Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster)
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
|
||||
clusterGetter := New(informer)
|
||||
t.Run(testCase.description, func(t *testing.T) {
|
||||
result, err := clusterGetter.List("", testCase.query)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(result, testCase.expected); len(diff) != 0 {
|
||||
t.Errorf("%T, got+ expected-, %s", testCase.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 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 clusterdashboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
monitoringdashboardv1alpha2 "kubesphere.io/monitoring-dashboard/api/v1alpha2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type dashboardGetter struct {
|
||||
c client.Reader
|
||||
}
|
||||
|
||||
func New(c client.Reader) v1alpha3.Interface {
|
||||
return &dashboardGetter{c}
|
||||
}
|
||||
|
||||
func (d *dashboardGetter) Get(_, name string) (runtime.Object, error) {
|
||||
dashboard := monitoringdashboardv1alpha2.ClusterDashboard{}
|
||||
err := d.c.Get(context.Background(), types.NamespacedName{Name: name}, &dashboard)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return &dashboard, nil
|
||||
}
|
||||
|
||||
func (d *dashboardGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
dashboards := monitoringdashboardv1alpha2.ClusterDashboardList{}
|
||||
err := d.c.List(context.Background(), &dashboards, &client.ListOptions{LabelSelector: query.Selector()})
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
for i := range dashboards.Items {
|
||||
result = append(result, &dashboards.Items[i])
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *dashboardGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftClusterDashboard, ok := left.(*monitoringdashboardv1alpha2.ClusterDashboard)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightClusterDashboard, ok := right.(*monitoringdashboardv1alpha2.ClusterDashboard)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftClusterDashboard.ObjectMeta, rightClusterDashboard.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *dashboardGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
dashboard, ok := object.(*monitoringdashboardv1alpha2.ClusterDashboard)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(dashboard.ObjectMeta, filter)
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 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 clusterdashboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
monitoringdashboardv1alpha2 "kubesphere.io/monitoring-dashboard/api/v1alpha2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
)
|
||||
|
||||
var c client.Client
|
||||
|
||||
func compare(actual *monitoringdashboardv1alpha2.ClusterDashboard,
|
||||
expects ...*monitoringdashboardv1alpha2.ClusterDashboard) bool {
|
||||
for _, app := range expects {
|
||||
if actual.Name == app.Name && reflect.DeepEqual(actual.Labels, app.Labels) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestGetListClusterDashboards(t *testing.T) {
|
||||
sch := scheme.Scheme
|
||||
if err := monitoringdashboardv1alpha2.AddToScheme(sch); err != nil {
|
||||
t.Fatalf("unable add APIs to scheme: %v", err)
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
c = fake.NewFakeClientWithScheme(sch)
|
||||
|
||||
var labelSet1 = map[string]string{"foo-1": "bar-1"}
|
||||
var labelSet2 = map[string]string{"foo-2": "bar-2"}
|
||||
|
||||
testCases := []*monitoringdashboardv1alpha2.ClusterDashboard{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "clusterdashboard-1",
|
||||
Labels: labelSet1,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "clusterdashboard-2",
|
||||
Labels: labelSet2,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
for _, board := range testCases {
|
||||
if err := c.Create(ctx, board); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
getter := New(c)
|
||||
|
||||
results, err := getter.List("", &query.Query{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if results.TotalItems != len(testCases) {
|
||||
t.Fatal("TotalItems is not match")
|
||||
}
|
||||
|
||||
if len(results.Items) != len(testCases) {
|
||||
t.Fatal("Items numbers is not match mock data")
|
||||
}
|
||||
|
||||
for _, dashboard := range results.Items {
|
||||
dashboard, err := dashboard.(*monitoringdashboardv1alpha2.ClusterDashboard)
|
||||
if !err {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !compare(dashboard, testCases...) {
|
||||
t.Errorf("The results %v not match testcases %v", results.Items, testCases)
|
||||
}
|
||||
}
|
||||
|
||||
result, err := getter.Get("", "clusterdashboard-1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dashboard := result.(*monitoringdashboardv1alpha2.ClusterDashboard)
|
||||
if !compare(dashboard, testCases...) {
|
||||
t.Errorf("The results %v not match testcases %v", result, testCases)
|
||||
}
|
||||
}
|
||||
@@ -1,75 +1,73 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package clusterrole
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
|
||||
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type clusterrolesGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
type clusterRolesGetter struct {
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &clusterrolesGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &clusterRolesGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *clusterrolesGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Rbac().V1().ClusterRoles().Lister().Get(name)
|
||||
func (d *clusterRolesGetter) Get(_, name string) (runtime.Object, error) {
|
||||
clusterRole := &rbacv1.ClusterRole{}
|
||||
return clusterRole, d.cache.Get(context.Background(), types.NamespacedName{Name: name}, clusterRole)
|
||||
}
|
||||
|
||||
func (d *clusterrolesGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
func (d *clusterRolesGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
var roles []*rbacv1.ClusterRole
|
||||
var err error
|
||||
|
||||
if aggregateTo := query.Filters[iamv1alpha2.AggregateTo]; aggregateTo != "" {
|
||||
if aggregateTo := query.Filters[iamv1beta1.AggregateTo]; aggregateTo != "" {
|
||||
roles, err = d.fetchAggregationRoles(string(aggregateTo))
|
||||
delete(query.Filters, iamv1alpha2.AggregateTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delete(query.Filters, iamv1beta1.AggregateTo)
|
||||
} else {
|
||||
roles, err = d.sharedInformers.Rbac().V1().ClusterRoles().Lister().List(query.Selector())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
clusterRoleList := &rbacv1.ClusterRoleList{}
|
||||
if err := d.cache.List(context.Background(), clusterRoleList,
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roles = make([]*rbacv1.ClusterRole, 0)
|
||||
for _, item := range clusterRoleList.Items {
|
||||
roles = append(roles, item.DeepCopy())
|
||||
}
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, clusterrole := range roles {
|
||||
result = append(result, clusterrole)
|
||||
for _, clusterRole := range roles {
|
||||
result = append(result, clusterRole)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *clusterrolesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
func (d *clusterRolesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftClusterRole, ok := left.(*rbacv1.ClusterRole)
|
||||
if !ok {
|
||||
return false
|
||||
@@ -83,7 +81,7 @@ func (d *clusterrolesGetter) compare(left runtime.Object, right runtime.Object,
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftClusterRole.ObjectMeta, rightClusterRole.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *clusterrolesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
func (d *clusterRolesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*rbacv1.ClusterRole)
|
||||
|
||||
if !ok {
|
||||
@@ -93,7 +91,7 @@ func (d *clusterrolesGetter) filter(object runtime.Object, filter query.Filter)
|
||||
return v1alpha3.DefaultObjectMetaFilter(role.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func (d *clusterrolesGetter) fetchAggregationRoles(name string) ([]*rbacv1.ClusterRole, error) {
|
||||
func (d *clusterRolesGetter) fetchAggregationRoles(name string) ([]*rbacv1.ClusterRole, error) {
|
||||
roles := make([]*rbacv1.ClusterRole, 0)
|
||||
|
||||
obj, err := d.Get("", name)
|
||||
@@ -105,7 +103,7 @@ func (d *clusterrolesGetter) fetchAggregationRoles(name string) ([]*rbacv1.Clust
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if annotation := obj.(*rbacv1.ClusterRole).Annotations[iamv1alpha2.AggregationRolesAnnotation]; annotation != "" {
|
||||
if annotation := obj.(*rbacv1.ClusterRole).Annotations[iamv1beta1.AggregationRolesAnnotation]; annotation != "" {
|
||||
var roleNames []string
|
||||
if err = json.Unmarshal([]byte(annotation), &roleNames); err == nil {
|
||||
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
//go:build exclude
|
||||
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
// TODO refactor with fake controller runtime client
|
||||
|
||||
package clusterrole
|
||||
|
||||
|
||||
@@ -1,61 +1,51 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package clusterrolebinding
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type clusterrolebindingsGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
type clusterRoleBindingsGetter struct {
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &clusterrolebindingsGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &clusterRoleBindingsGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *clusterrolebindingsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Rbac().V1().ClusterRoleBindings().Lister().Get(name)
|
||||
func (d *clusterRoleBindingsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
clusterRoleBinding := &rbacv1.ClusterRoleBinding{}
|
||||
return clusterRoleBinding, d.cache.Get(context.Background(), types.NamespacedName{Name: name}, clusterRoleBinding)
|
||||
}
|
||||
|
||||
func (d *clusterrolebindingsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
roleBindings, err := d.sharedInformers.Rbac().V1().ClusterRoleBindings().Lister().List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
func (d *clusterRoleBindingsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
clusterRoleBindings := &rbacv1.ClusterRoleBindingList{}
|
||||
if err := d.cache.List(context.Background(), clusterRoleBindings,
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, roleBinding := range roleBindings {
|
||||
result = append(result, roleBinding)
|
||||
for _, item := range clusterRoleBindings.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *clusterrolebindingsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
func (d *clusterRoleBindingsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftRoleBinding, ok := left.(*rbacv1.ClusterRoleBinding)
|
||||
if !ok {
|
||||
return false
|
||||
@@ -69,7 +59,7 @@ func (d *clusterrolebindingsGetter) compare(left runtime.Object, right runtime.O
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRoleBinding.ObjectMeta, rightRoleBinding.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *clusterrolebindingsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
func (d *clusterRoleBindingsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*rbacv1.ClusterRoleBinding)
|
||||
|
||||
if !ok {
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
//go:build exclude
|
||||
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
// TODO refactor with fake controller runtime client
|
||||
|
||||
package clusterrolebinding
|
||||
|
||||
|
||||
@@ -1,25 +1,18 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package configmap
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -27,33 +20,32 @@ import (
|
||||
)
|
||||
|
||||
type configmapsGetter struct {
|
||||
informer informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &configmapsGetter{informer: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &configmapsGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *configmapsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.informer.Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).Get(name)
|
||||
configMap := &corev1.ConfigMap{}
|
||||
return configMap, d.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, configMap)
|
||||
}
|
||||
|
||||
func (d *configmapsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
configmaps, err := d.informer.Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
configMaps := &corev1.ConfigMapList{}
|
||||
if err := d.cache.List(context.Background(), configMaps, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, configmap := range configmaps {
|
||||
result = append(result, configmap)
|
||||
for _, item := range configMaps.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *configmapsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftCM, ok := left.(*corev1.ConfigMap)
|
||||
if !ok {
|
||||
return false
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
//go:build exclude
|
||||
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
// TODO refactor with fake controller runtime client
|
||||
|
||||
package configmap
|
||||
|
||||
|
||||
112
pkg/models/resources/v1alpha3/cronjob/cronjobs.go
Normal file
112
pkg/models/resources/v1alpha3/cronjob/cronjobs.go
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package cronjob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/scheme"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
)
|
||||
|
||||
type cronJobsGetter struct {
|
||||
cache runtimeclient.Reader
|
||||
gvk schema.GroupVersionKind
|
||||
listGVK schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func New(cache runtimeclient.Reader, k8sVersion *semver.Version) v1alpha3.Interface {
|
||||
gvk := batchv1.SchemeGroupVersion.WithKind("CronJob")
|
||||
listGVK := schema.GroupVersionKind{
|
||||
Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
Kind: gvk.Kind + "List",
|
||||
}
|
||||
if k8sutil.ServeBatchV1beta1(k8sVersion) {
|
||||
gvk.Version = "v1beta1"
|
||||
listGVK.Version = "v1beta1"
|
||||
}
|
||||
return &cronJobsGetter{
|
||||
cache: cache,
|
||||
gvk: gvk,
|
||||
listGVK: listGVK,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *cronJobsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
obj, err := scheme.Scheme.New(d.gvk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cronJob := obj.(client.Object)
|
||||
return cronJob, d.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, cronJob)
|
||||
}
|
||||
|
||||
func (d *cronJobsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
listObj := &unstructured.UnstructuredList{}
|
||||
listObj.SetGroupVersionKind(d.listGVK)
|
||||
|
||||
if err := d.cache.List(context.Background(), listObj, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
if err := listObj.EachListItem(func(object runtime.Object) error {
|
||||
result = append(result, object)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func cronJobStatus(item *unstructured.Unstructured) string {
|
||||
suspend, _, _ := unstructured.NestedBool(item.UnstructuredContent(), "spec", "suspend")
|
||||
if suspend {
|
||||
return "paused"
|
||||
}
|
||||
return "running"
|
||||
}
|
||||
|
||||
func (d *cronJobsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
job, ok := object.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch filter.Field {
|
||||
case query.FieldStatus:
|
||||
return strings.Compare(cronJobStatus(job), string(filter.Value)) == 0
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(k8sutil.GetObjectMeta(job), filter)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *cronJobsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftJob, ok := left.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightJob, ok := right.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(k8sutil.GetObjectMeta(leftJob), k8sutil.GetObjectMeta(rightJob), field)
|
||||
}
|
||||
@@ -1,26 +1,19 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package customresourcedefinition
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
@@ -29,30 +22,28 @@ import (
|
||||
)
|
||||
|
||||
type crdGetter struct {
|
||||
informers apiextensionsinformers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(informers apiextensionsinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &crdGetter{
|
||||
informers: informers,
|
||||
}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &crdGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (c crdGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return c.informers.Apiextensions().V1().CustomResourceDefinitions().Lister().Get(name)
|
||||
crd := &v1.CustomResourceDefinition{}
|
||||
return crd, c.cache.Get(context.Background(), types.NamespacedName{Name: name}, crd)
|
||||
}
|
||||
|
||||
func (c crdGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
crds, err := c.informers.Apiextensions().V1().CustomResourceDefinitions().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
crds := &v1.CustomResourceDefinitionList{}
|
||||
if err := c.cache.List(context.Background(), crds,
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, crd := range crds {
|
||||
result = append(result, crd)
|
||||
for _, item := range crds.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, c.compare, c.filter), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package customresourcedefinition
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
fakeapiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
|
||||
apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
)
|
||||
|
||||
var crds = []*v1.CustomResourceDefinition{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "clusters.cluster.kubesphere.io",
|
||||
Labels: map[string]string{
|
||||
"controller-tools.k8s.io": "1.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "workspaces.tenant.kubesphere.io",
|
||||
Labels: map[string]string{
|
||||
"controller-tools.k8s.io": "1.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func crdsToRuntimeObjects(crds ...*v1.CustomResourceDefinition) []runtime.Object {
|
||||
items := make([]runtime.Object, 0)
|
||||
|
||||
for _, crd := range crds {
|
||||
items = append(items, crd)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func crdsToInterface(crds ...*v1.CustomResourceDefinition) []interface{} {
|
||||
items := make([]interface{}, 0)
|
||||
|
||||
for _, crd := range crds {
|
||||
items = append(items, crd)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func TestCrdGetterList(t *testing.T) {
|
||||
var testCases = []struct {
|
||||
description string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
}{
|
||||
{
|
||||
description: "Test normal case",
|
||||
query: &query.Query{
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldName: "clusters.cluster.kubesphere.io",
|
||||
},
|
||||
},
|
||||
expected: &api.ListResult{
|
||||
TotalItems: 1,
|
||||
Items: crdsToInterface(crds[0]),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
client := fakeapiextensions.NewSimpleClientset(crdsToRuntimeObjects(crds...)...)
|
||||
informers := apiextensionsinformers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, crd := range crds {
|
||||
informers.Apiextensions().V1().CustomResourceDefinitions().Informer().GetIndexer().Add(crd)
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
|
||||
crdGetter := New(informers)
|
||||
|
||||
t.Run(testCase.description, func(t *testing.T) {
|
||||
result, err := crdGetter.List("", testCase.query)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(result, testCase.expected); len(diff) != 0 {
|
||||
t.Errorf("%T, got+ expected-, %s", testCase.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,20 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package daemonset
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -35,34 +28,32 @@ const (
|
||||
)
|
||||
|
||||
type daemonSetGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &daemonSetGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &daemonSetGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *daemonSetGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Apps().V1().DaemonSets().Lister().DaemonSets(namespace).Get(name)
|
||||
daemonSet := &appsv1.DaemonSet{}
|
||||
return daemonSet, d.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, daemonSet)
|
||||
}
|
||||
|
||||
func (d *daemonSetGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
// first retrieves all daemonSets within given namespace
|
||||
daemonSets, err := d.sharedInformers.Apps().V1().DaemonSets().Lister().DaemonSets(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
daemonSets := &appsv1.DaemonSetList{}
|
||||
if err := d.cache.List(context.Background(), daemonSets, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, daemonSet := range daemonSets {
|
||||
result = append(result, daemonSet)
|
||||
for _, item := range daemonSets.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *daemonSetGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftDaemonSet, ok := left.(*appsv1.DaemonSet)
|
||||
if !ok {
|
||||
return false
|
||||
@@ -83,13 +74,13 @@ func (d *daemonSetGetter) filter(object runtime.Object, filter query.Filter) boo
|
||||
}
|
||||
switch filter.Field {
|
||||
case query.FieldStatus:
|
||||
return strings.Compare(daemonsetStatus(&daemonSet.Status), string(filter.Value)) == 0
|
||||
return strings.Compare(daemonSetStatus(&daemonSet.Status), string(filter.Value)) == 0
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(daemonSet.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
|
||||
func daemonsetStatus(status *appsv1.DaemonSetStatus) string {
|
||||
func daemonSetStatus(status *appsv1.DaemonSetStatus) string {
|
||||
if status.DesiredNumberScheduled == 0 && status.NumberReady == 0 {
|
||||
return statusStopped
|
||||
} else if status.DesiredNumberScheduled == status.NumberReady {
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
//go:build exclude
|
||||
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
// TODO refactor with fake controller runtime client
|
||||
|
||||
package daemonset
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 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 dashboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
monitoringdashboardv1alpha2 "kubesphere.io/monitoring-dashboard/api/v1alpha2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type dashboardGetter struct {
|
||||
c client.Reader
|
||||
}
|
||||
|
||||
func New(c client.Reader) v1alpha3.Interface {
|
||||
return &dashboardGetter{c}
|
||||
}
|
||||
|
||||
func (d *dashboardGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
dashboard := monitoringdashboardv1alpha2.Dashboard{}
|
||||
err := d.c.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, &dashboard)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return &dashboard, nil
|
||||
}
|
||||
|
||||
func (d *dashboardGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
dashboards := monitoringdashboardv1alpha2.DashboardList{}
|
||||
err := d.c.List(context.Background(), &dashboards, &client.ListOptions{Namespace: namespace, LabelSelector: query.Selector()})
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
for i := range dashboards.Items {
|
||||
result = append(result, &dashboards.Items[i])
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *dashboardGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftDashboard, ok := left.(*monitoringdashboardv1alpha2.Dashboard)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightDashboard, ok := right.(*monitoringdashboardv1alpha2.Dashboard)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftDashboard.ObjectMeta, rightDashboard.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *dashboardGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
dashboard, ok := object.(*monitoringdashboardv1alpha2.Dashboard)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(dashboard.ObjectMeta, filter)
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 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 dashboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
monitoringdashboardv1alpha2 "kubesphere.io/monitoring-dashboard/api/v1alpha2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
)
|
||||
|
||||
var c client.Client
|
||||
|
||||
func compare(actual *monitoringdashboardv1alpha2.Dashboard, expects ...*monitoringdashboardv1alpha2.Dashboard) bool {
|
||||
for _, app := range expects {
|
||||
if actual.Name == app.Name && actual.Namespace == app.Namespace && reflect.DeepEqual(actual.Labels, app.Labels) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestGetListDashboards(t *testing.T) {
|
||||
sch := scheme.Scheme
|
||||
if err := monitoringdashboardv1alpha2.AddToScheme(sch); err != nil {
|
||||
t.Fatalf("unable add APIs to scheme: %v", err)
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
c = fake.NewFakeClientWithScheme(sch)
|
||||
|
||||
var labelSet1 = map[string]string{"foo-1": "bar-1"}
|
||||
var labelSet2 = map[string]string{"foo-2": "bar-2"}
|
||||
|
||||
var ns = "ns-1"
|
||||
testCases := []*monitoringdashboardv1alpha2.Dashboard{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "dashboard-1",
|
||||
Namespace: ns,
|
||||
Labels: labelSet1,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "dashboard-2",
|
||||
Namespace: ns,
|
||||
Labels: labelSet2,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
for _, board := range testCases {
|
||||
if err := c.Create(ctx, board); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
getter := New(c)
|
||||
|
||||
results, err := getter.List(ns, &query.Query{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if results.TotalItems != len(testCases) {
|
||||
t.Fatal("TotalItems is not match")
|
||||
}
|
||||
|
||||
if len(results.Items) != len(testCases) {
|
||||
t.Fatal("Items numbers is not match mock data")
|
||||
}
|
||||
|
||||
for _, dashboard := range results.Items {
|
||||
dashboard, err := dashboard.(*monitoringdashboardv1alpha2.Dashboard)
|
||||
if !err {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !compare(dashboard, testCases...) {
|
||||
t.Errorf("The results %v not match testcases %v", results.Items, testCases)
|
||||
}
|
||||
}
|
||||
|
||||
result, err := getter.Get(ns, "dashboard-1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dashboard := result.(*monitoringdashboardv1alpha2.Dashboard)
|
||||
if !compare(dashboard, testCases...) {
|
||||
t.Errorf("The results %v not match testcases %v", result, testCases)
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,26 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package deployment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -37,40 +30,38 @@ const (
|
||||
)
|
||||
|
||||
type deploymentsGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &deploymentsGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &deploymentsGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *deploymentsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Apps().V1().Deployments().Lister().Deployments(namespace).Get(name)
|
||||
deployment := &appsv1.Deployment{}
|
||||
return deployment, d.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, deployment)
|
||||
}
|
||||
|
||||
func (d *deploymentsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
// first retrieves all deployments within given namespace
|
||||
deployments, err := d.sharedInformers.Apps().V1().Deployments().Lister().Deployments(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
deployments := &appsv1.DeploymentList{}
|
||||
if err := d.cache.List(context.Background(), deployments, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, deployment := range deployments {
|
||||
result = append(result, deployment)
|
||||
for _, item := range deployments.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *deploymentsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftDeployment, ok := left.(*v1.Deployment)
|
||||
leftDeployment, ok := left.(*appsv1.Deployment)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightDeployment, ok := right.(*v1.Deployment)
|
||||
rightDeployment, ok := right.(*appsv1.Deployment)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -86,7 +77,7 @@ func (d *deploymentsGetter) compare(left runtime.Object, right runtime.Object, f
|
||||
}
|
||||
|
||||
func (d *deploymentsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
deployment, ok := object.(*v1.Deployment)
|
||||
deployment, ok := object.(*appsv1.Deployment)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -99,7 +90,7 @@ func (d *deploymentsGetter) filter(object runtime.Object, filter query.Filter) b
|
||||
}
|
||||
}
|
||||
|
||||
func deploymentStatus(status v1.DeploymentStatus) string {
|
||||
func deploymentStatus(status appsv1.DeploymentStatus) string {
|
||||
if status.ReadyReplicas == 0 && status.Replicas == 0 {
|
||||
return statusStopped
|
||||
} else if status.ReadyReplicas == status.Replicas {
|
||||
@@ -109,7 +100,7 @@ func deploymentStatus(status v1.DeploymentStatus) string {
|
||||
}
|
||||
}
|
||||
|
||||
func lastUpdateTime(deployment *v1.Deployment) time.Time {
|
||||
func lastUpdateTime(deployment *appsv1.Deployment) time.Time {
|
||||
lut := deployment.CreationTimestamp.Time
|
||||
for _, condition := range deployment.Status.Conditions {
|
||||
if condition.LastUpdateTime.After(lut) {
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
//go:build exclude
|
||||
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
// TODO refactor with fake controller runtime client
|
||||
|
||||
package deployment
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package devops
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
devopsv1alpha3 "kubesphere.io/api/devops/v1alpha3"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type devopsGetter struct {
|
||||
informers ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(ksinformer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &devopsGetter{informers: ksinformer}
|
||||
}
|
||||
|
||||
func (n devopsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return n.informers.Devops().V1alpha3().DevOpsProjects().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (n devopsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
projects, err := n.informers.Devops().V1alpha3().DevOpsProjects().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, project := range projects {
|
||||
result = append(result, project)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, n.compare, n.filter), nil
|
||||
}
|
||||
|
||||
func (n devopsGetter) filter(item runtime.Object, filter query.Filter) bool {
|
||||
devOpsProject, ok := item.(*devopsv1alpha3.DevOpsProject)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaFilter(devOpsProject.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func (n devopsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftProject, ok := left.(*devopsv1alpha3.DevOpsProject)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightProject, ok := right.(*devopsv1alpha3.DevOpsProject)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftProject.ObjectMeta, rightProject.ObjectMeta, field)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package devops
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedapplication
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type fedApplicationsGetter struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &fedApplicationsGetter{informer: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *fedApplicationsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.informer.Types().V1beta1().FederatedApplications().Lister().FederatedApplications(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (d *fedApplicationsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
applications, err := d.informer.Types().V1beta1().FederatedApplications().Lister().FederatedApplications(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, app := range applications {
|
||||
result = append(result, app)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *fedApplicationsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftApplication, ok := left.(*v1beta1.FederatedApplication)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightApplication, ok := right.(*v1beta1.FederatedApplication)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch field {
|
||||
case query.FieldUpdateTime:
|
||||
fallthrough
|
||||
case query.FieldLastUpdateTimestamp:
|
||||
return lastUpdateTime(leftApplication) > (lastUpdateTime(rightApplication))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftApplication.ObjectMeta, rightApplication.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *fedApplicationsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
application, ok := object.(*v1beta1.FederatedApplication)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(application.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func lastUpdateTime(application *v1beta1.FederatedApplication) string {
|
||||
lut := application.CreationTimestamp.Time.String()
|
||||
for _, condition := range application.Status.Conditions {
|
||||
if condition.LastUpdateTime > lut {
|
||||
lut = condition.LastUpdateTime
|
||||
}
|
||||
}
|
||||
return lut
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedconfigmap
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type fedConfigMapsGetter struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &fedConfigMapsGetter{informer: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *fedConfigMapsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.informer.Types().V1beta1().FederatedConfigMaps().Lister().FederatedConfigMaps(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (d *fedConfigMapsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
configmaps, err := d.informer.Types().V1beta1().FederatedConfigMaps().Lister().FederatedConfigMaps(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, configmap := range configmaps {
|
||||
result = append(result, configmap)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *fedConfigMapsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftCM, ok := left.(*v1beta1.FederatedConfigMap)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightCM, ok := right.(*v1beta1.FederatedConfigMap)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftCM.ObjectMeta, rightCM.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *fedConfigMapsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
configMap, ok := object.(*v1beta1.FederatedConfigMap)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(configMap.ObjectMeta, filter)
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 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 federateddeployment
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type fedreatedDeploymentGetter struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informer informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &fedreatedDeploymentGetter{
|
||||
informer: informer,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *fedreatedDeploymentGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return f.informer.Types().V1beta1().FederatedDeployments().Lister().FederatedDeployments(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (f *fedreatedDeploymentGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
federatedDeployments, err := f.informer.Types().V1beta1().FederatedDeployments().Lister().FederatedDeployments(namespace).List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, fedDeployment := range federatedDeployments {
|
||||
result = append(result, fedDeployment)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, f.compare, f.filter), nil
|
||||
}
|
||||
|
||||
func (f *fedreatedDeploymentGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftFedDeployment, ok := left.(*v1beta1.FederatedDeployment)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightFedDeployment, ok := right.(*v1beta1.FederatedDeployment)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch field {
|
||||
case query.FieldUpdateTime:
|
||||
fallthrough
|
||||
case query.FieldLastUpdateTimestamp:
|
||||
return lastUpdateTime(leftFedDeployment) > lastUpdateTime(rightFedDeployment)
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftFedDeployment.ObjectMeta, rightFedDeployment.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *fedreatedDeploymentGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
fedDeployment, ok := object.(*v1beta1.FederatedDeployment)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(fedDeployment.ObjectMeta, filter)
|
||||
|
||||
}
|
||||
|
||||
func lastUpdateTime(fedDeployment *v1beta1.FederatedDeployment) string {
|
||||
lut := fedDeployment.CreationTimestamp.Time.String()
|
||||
for _, condition := range fedDeployment.Status.Conditions {
|
||||
if condition.LastUpdateTime > lut {
|
||||
lut = condition.LastUpdateTime
|
||||
}
|
||||
}
|
||||
return lut
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package federatedingress
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type fedIngressGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &fedIngressGetter{sharedInformers: sharedInformers}
|
||||
}
|
||||
|
||||
func (g *fedIngressGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return g.sharedInformers.Types().V1beta1().FederatedIngresses().Lister().FederatedIngresses(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (g *fedIngressGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
// first retrieves all deployments within given namespace
|
||||
ingresses, err := g.sharedInformers.Types().V1beta1().FederatedIngresses().Lister().FederatedIngresses(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, ingress := range ingresses {
|
||||
result = append(result, ingress)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, g.compare, g.filter), nil
|
||||
}
|
||||
|
||||
func (g *fedIngressGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftIngress, ok := left.(*v1beta1.FederatedIngress)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightIngress, ok := right.(*v1beta1.FederatedIngress)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftIngress.ObjectMeta, rightIngress.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (g *fedIngressGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
deployment, ok := object.(*v1beta1.FederatedIngress)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaFilter(deployment.ObjectMeta, filter)
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatednamespace
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
typesv1beta1 "kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type federatedNamespacesGetter struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &federatedNamespacesGetter{informers: informers}
|
||||
}
|
||||
|
||||
func (n federatedNamespacesGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return n.informers.Types().V1beta1().FederatedNamespaces().Lister().FederatedNamespaces(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (n federatedNamespacesGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
ns, err := n.informers.Types().V1beta1().FederatedNamespaces().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, item := range ns {
|
||||
result = append(result, item)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, n.compare, n.filter), nil
|
||||
}
|
||||
|
||||
func (n federatedNamespacesGetter) filter(item runtime.Object, filter query.Filter) bool {
|
||||
namespace, ok := item.(*typesv1beta1.FederatedNamespace)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaFilter(namespace.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func (n federatedNamespacesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftNs, ok := left.(*typesv1beta1.FederatedNamespace)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightNs, ok := right.(*typesv1beta1.FederatedNamespace)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftNs.ObjectMeta, rightNs.ObjectMeta, field)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatednamespace
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedpersistentvolumeclaim
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
const (
|
||||
storageClassName = "storageClassName"
|
||||
)
|
||||
|
||||
type fedPersistentVolumeClaimGetter struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informer informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &fedPersistentVolumeClaimGetter{informers: informer}
|
||||
}
|
||||
|
||||
func (p *fedPersistentVolumeClaimGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return p.informers.Types().V1beta1().FederatedPersistentVolumeClaims().Lister().FederatedPersistentVolumeClaims(namespace).Get(name)
|
||||
|
||||
}
|
||||
|
||||
func (p *fedPersistentVolumeClaimGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
all, err := p.informers.Types().V1beta1().FederatedPersistentVolumeClaims().Lister().FederatedPersistentVolumeClaims(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, pvc := range all {
|
||||
result = append(result, pvc)
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, p.compare, p.filter), nil
|
||||
}
|
||||
|
||||
func (p *fedPersistentVolumeClaimGetter) compare(left, right runtime.Object, field query.Field) bool {
|
||||
leftSnapshot, ok := left.(*v1beta1.FederatedPersistentVolumeClaim)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
rightSnapshot, ok := right.(*v1beta1.FederatedPersistentVolumeClaim)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftSnapshot.ObjectMeta, rightSnapshot.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (p *fedPersistentVolumeClaimGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
pvc, ok := object.(*v1beta1.FederatedPersistentVolumeClaim)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case storageClassName:
|
||||
return pvc.Spec.Template.Spec.StorageClassName != nil && *pvc.Spec.Template.Spec.StorageClassName == string(filter.Value)
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(pvc.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
package federatedpersistentvolumeclaim
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
fedv1beta1 "kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
var (
|
||||
testStorageClassName = "sc1"
|
||||
)
|
||||
|
||||
var (
|
||||
pvc1 = &fedv1beta1.FederatedPersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-1",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
|
||||
pvc2 = &fedv1beta1.FederatedPersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-2",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: fedv1beta1.FederatedPersistentVolumeClaimSpec{
|
||||
Template: fedv1beta1.PersistentVolumeClaimTemplate{
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
StorageClassName: &testStorageClassName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pvc3 = &fedv1beta1.FederatedPersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-3",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"kubesphere.io/in-use": "false",
|
||||
},
|
||||
},
|
||||
Spec: fedv1beta1.FederatedPersistentVolumeClaimSpec{
|
||||
Template: fedv1beta1.PersistentVolumeClaimTemplate{
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
StorageClassName: &testStorageClassName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
federatedPersistentVolumeClaims = []*fedv1beta1.FederatedPersistentVolumeClaim{pvc1, pvc2, pvc3}
|
||||
)
|
||||
|
||||
func fedPVCsToInterface(federatedPersistentVolumeClaims ...*fedv1beta1.FederatedPersistentVolumeClaim) []interface{} {
|
||||
items := make([]interface{}, 0)
|
||||
|
||||
for _, fedPVC := range federatedPersistentVolumeClaims {
|
||||
items = append(items, fedPVC)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func fedPVCsToRuntimeObject(federatedPersistentVolumeClaims ...*fedv1beta1.FederatedPersistentVolumeClaim) []runtime.Object {
|
||||
items := make([]runtime.Object, 0)
|
||||
|
||||
for _, fedPVC := range federatedPersistentVolumeClaims {
|
||||
items = append(items, fedPVC)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func prepare() (v1alpha3.Interface, error) {
|
||||
client := fake.NewSimpleClientset(fedPVCsToRuntimeObject(federatedPersistentVolumeClaims...)...)
|
||||
informer := externalversions.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, fedPVC := range federatedPersistentVolumeClaims {
|
||||
err := informer.Types().V1beta1().FederatedPersistentVolumeClaims().Informer().GetIndexer().Add(fedPVC)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return New(informer), nil
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
tests := []struct {
|
||||
namespace string
|
||||
name string
|
||||
expected runtime.Object
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
namespace: "default",
|
||||
name: "pvc-1",
|
||||
expected: fedPVCsToRuntimeObject(pvc1)[0],
|
||||
expectedErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter, err := prepare()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
pvc, err := getter.Get(test.namespace, test.name)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
diff := cmp.Diff(pvc, test.expected)
|
||||
if diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
description: "test name filter",
|
||||
namespace: "default",
|
||||
query: &query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value(pvc1.Name)},
|
||||
},
|
||||
expected: &api.ListResult{
|
||||
Items: fedPVCsToInterface(federatedPersistentVolumeClaims[0]),
|
||||
TotalItems: 1,
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
description: "test storageClass filter",
|
||||
namespace: "default",
|
||||
query: &query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.Field(storageClassName): query.Value(*pvc2.Spec.Template.Spec.StorageClassName)},
|
||||
},
|
||||
expected: &api.ListResult{
|
||||
Items: fedPVCsToInterface(federatedPersistentVolumeClaims[2], federatedPersistentVolumeClaims[1]),
|
||||
TotalItems: 2,
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
description: "test label filter",
|
||||
namespace: "default",
|
||||
query: &query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
LabelSelector: "kubesphere.io/in-use=false",
|
||||
Filters: map[query.Field]query.Value{query.Field(storageClassName): query.Value(*pvc2.Spec.Template.Spec.StorageClassName)},
|
||||
},
|
||||
expected: &api.ListResult{
|
||||
Items: fedPVCsToInterface(federatedPersistentVolumeClaims[2]),
|
||||
TotalItems: 1,
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
lister, err := prepare()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := lister.List(test.namespace, test.query)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("[%s] %T differ (-got, +want): %s", test.description, test.expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedsecret
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type fedSecretGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &fedSecretGetter{sharedInformers: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *fedSecretGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Types().V1beta1().FederatedSecrets().Lister().FederatedSecrets(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (d *fedSecretGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
secrets, err := d.sharedInformers.Types().V1beta1().FederatedSecrets().Lister().FederatedSecrets(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, secret := range secrets {
|
||||
result = append(result, secret)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *fedSecretGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftSecret, ok := left.(*v1beta1.FederatedSecret)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightSecret, ok := right.(*v1beta1.FederatedSecret)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftSecret.ObjectMeta, rightSecret.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *fedSecretGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
fedSecret, ok := object.(*v1beta1.FederatedSecret)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldType:
|
||||
return strings.Compare(string(fedSecret.Spec.Template.Type), string(filter.Value)) == 0
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(fedSecret.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 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 federatedservice
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type federatedServiceGetter struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informer informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &federatedServiceGetter{
|
||||
informer: informer,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *federatedServiceGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return f.informer.Types().V1beta1().FederatedServices().Lister().FederatedServices(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (f *federatedServiceGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
federatedServices, err := f.informer.Types().V1beta1().FederatedServices().Lister().FederatedServices(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, fedService := range federatedServices {
|
||||
result = append(result, fedService)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, f.compare, f.filter), nil
|
||||
}
|
||||
|
||||
func (f *federatedServiceGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftService, ok := left.(*v1beta1.FederatedService)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightService, ok := right.(*v1beta1.FederatedService)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftService.ObjectMeta, rightService.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (f *federatedServiceGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
service, ok := object.(*v1beta1.FederatedService)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(service.ObjectMeta, filter)
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package federatedstatefulset
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/types/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type fedStatefulSetGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &fedStatefulSetGetter{sharedInformers: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *fedStatefulSetGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Types().V1beta1().FederatedStatefulSets().Lister().FederatedStatefulSets(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (d *fedStatefulSetGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
// first retrieves all statefulSets within given namespace
|
||||
statefulSets, err := d.sharedInformers.Types().V1beta1().FederatedStatefulSets().Lister().FederatedStatefulSets(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, statefulSet := range statefulSets {
|
||||
result = append(result, statefulSet)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *fedStatefulSetGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftStatefulSet, ok := left.(*v1beta1.FederatedStatefulSet)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightStatefulSet, ok := right.(*v1beta1.FederatedStatefulSet)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftStatefulSet.ObjectMeta, rightStatefulSet.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *fedStatefulSetGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
statefulSet, ok := object.(*v1beta1.FederatedStatefulSet)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(statefulSet.ObjectMeta, filter)
|
||||
}
|
||||
@@ -1,62 +1,61 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package globalrole
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
|
||||
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type globalrolesGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
type globalRolesGetter struct {
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &globalrolesGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &globalRolesGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Iam().V1alpha2().GlobalRoles().Lister().Get(name)
|
||||
func (d *globalRolesGetter) Get(_, name string) (runtime.Object, error) {
|
||||
globalRole := &iamv1beta1.GlobalRole{}
|
||||
return globalRole, d.cache.Get(context.Background(), types.NamespacedName{Name: name}, globalRole)
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
var roles []*iamv1alpha2.GlobalRole
|
||||
func (d *globalRolesGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
var roles []*iamv1beta1.GlobalRole
|
||||
var err error
|
||||
|
||||
if aggregateTo := query.Filters[iamv1alpha2.AggregateTo]; aggregateTo != "" {
|
||||
if aggregateTo := query.Filters[iamv1beta1.AggregateTo]; aggregateTo != "" {
|
||||
roles, err = d.fetchAggregationRoles(string(aggregateTo))
|
||||
delete(query.Filters, iamv1alpha2.AggregateTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delete(query.Filters, iamv1beta1.AggregateTo)
|
||||
} else {
|
||||
roles, err = d.sharedInformers.Iam().V1alpha2().GlobalRoles().Lister().List(query.Selector())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
globalRoleList := &iamv1beta1.GlobalRoleList{}
|
||||
if err := d.cache.List(context.Background(), globalRoleList,
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roles = make([]*iamv1beta1.GlobalRole, 0)
|
||||
for _, item := range globalRoleList.Items {
|
||||
roles = append(roles, item.DeepCopy())
|
||||
}
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
@@ -67,14 +66,13 @@ func (d *globalrolesGetter) List(_ string, query *query.Query) (*api.ListResult,
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftRole, ok := left.(*iamv1alpha2.GlobalRole)
|
||||
func (d *globalRolesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftRole, ok := left.(*iamv1beta1.GlobalRole)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightRole, ok := right.(*iamv1alpha2.GlobalRole)
|
||||
rightRole, ok := right.(*iamv1beta1.GlobalRole)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -82,8 +80,8 @@ func (d *globalrolesGetter) compare(left runtime.Object, right runtime.Object, f
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRole.ObjectMeta, rightRole.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*iamv1alpha2.GlobalRole)
|
||||
func (d *globalRolesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*iamv1beta1.GlobalRole)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
@@ -92,8 +90,8 @@ func (d *globalrolesGetter) filter(object runtime.Object, filter query.Filter) b
|
||||
return v1alpha3.DefaultObjectMetaFilter(role.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) fetchAggregationRoles(name string) ([]*iamv1alpha2.GlobalRole, error) {
|
||||
roles := make([]*iamv1alpha2.GlobalRole, 0)
|
||||
func (d *globalRolesGetter) fetchAggregationRoles(name string) ([]*iamv1beta1.GlobalRole, error) {
|
||||
roles := make([]*iamv1beta1.GlobalRole, 0)
|
||||
|
||||
obj, err := d.Get("", name)
|
||||
|
||||
@@ -104,7 +102,7 @@ func (d *globalrolesGetter) fetchAggregationRoles(name string) ([]*iamv1alpha2.G
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if annotation := obj.(*iamv1alpha2.GlobalRole).Annotations[iamv1alpha2.AggregationRolesAnnotation]; annotation != "" {
|
||||
if annotation := obj.(*iamv1beta1.GlobalRole).Annotations[iamv1beta1.AggregationRolesAnnotation]; annotation != "" {
|
||||
var roleNames []string
|
||||
if err = json.Unmarshal([]byte(annotation), &roleNames); err == nil {
|
||||
|
||||
@@ -119,7 +117,7 @@ func (d *globalrolesGetter) fetchAggregationRoles(name string) ([]*iamv1alpha2.G
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles = append(roles, role.(*iamv1alpha2.GlobalRole))
|
||||
roles = append(roles, role.(*iamv1beta1.GlobalRole))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package globalrole
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListGlobalRoles(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &iamv1alpha2.GlobalRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &iamv1alpha2.GlobalRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
bar1 = &iamv1alpha2.GlobalRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
},
|
||||
}
|
||||
|
||||
roles = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, role := range roles {
|
||||
informer.Iam().V1alpha2().GlobalRoles().Informer().GetIndexer().Add(role)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,68 +1,57 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package globalrolebinding
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"context"
|
||||
|
||||
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type globalrolebindingsGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
type globalRoleBindingsGetter struct {
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &globalrolebindingsGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &globalRoleBindingsGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *globalrolebindingsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Iam().V1alpha2().GlobalRoleBindings().Lister().Get(name)
|
||||
func (d *globalRoleBindingsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
globalRoleBinding := &iamv1beta1.GlobalRoleBinding{}
|
||||
return globalRoleBinding, d.cache.Get(context.Background(), types.NamespacedName{Name: name}, globalRoleBinding)
|
||||
}
|
||||
|
||||
func (d *globalrolebindingsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
globalRoleBindings, err := d.sharedInformers.Iam().V1alpha2().GlobalRoleBindings().Lister().List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
func (d *globalRoleBindingsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
globalRoleBindings := &iamv1beta1.GlobalRoleBindingList{}
|
||||
if err := d.cache.List(context.Background(), globalRoleBindings,
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, globalRoleBinding := range globalRoleBindings {
|
||||
result = append(result, globalRoleBinding)
|
||||
for _, item := range globalRoleBindings.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *globalrolebindingsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftRoleBinding, ok := left.(*iamv1alpha2.GlobalRoleBinding)
|
||||
func (d *globalRoleBindingsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftRoleBinding, ok := left.(*iamv1beta1.GlobalRoleBinding)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightRoleBinding, ok := right.(*iamv1alpha2.GlobalRoleBinding)
|
||||
rightRoleBinding, ok := right.(*iamv1beta1.GlobalRoleBinding)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -70,8 +59,8 @@ func (d *globalrolebindingsGetter) compare(left runtime.Object, right runtime.Ob
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRoleBinding.ObjectMeta, rightRoleBinding.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *globalrolebindingsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*iamv1alpha2.GlobalRoleBinding)
|
||||
func (d *globalRoleBindingsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*iamv1beta1.GlobalRoleBinding)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package globalrolebinding
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListRoles(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List("", test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &iamv1alpha2.GlobalRoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &iamv1alpha2.GlobalRoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
bar1 = &iamv1alpha2.GlobalRoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
|
||||
globalRoleBindings = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, globalRoleBinding := range globalRoleBindings {
|
||||
informer.Iam().V1alpha2().GlobalRoleBindings().Informer().GetIndexer().Add(globalRoleBinding)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,67 +1,57 @@
|
||||
/*
|
||||
Copyright 2020 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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package group
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"context"
|
||||
|
||||
"kubesphere.io/api/iam/v1alpha2"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type groupGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &groupGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &groupGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *groupGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Iam().V1alpha2().Groups().Lister().Get(name)
|
||||
group := &iamv1beta1.Group{}
|
||||
return group, d.cache.Get(context.Background(), types.NamespacedName{Name: name}, group)
|
||||
}
|
||||
|
||||
func (d *groupGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
groups, err := d.sharedInformers.Iam().V1alpha2().Groups().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
groups := &iamv1beta1.GroupList{}
|
||||
if err := d.cache.List(context.Background(), groups,
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, group := range groups {
|
||||
result = append(result, group)
|
||||
for _, item := range groups.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *groupGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftGroup, ok := left.(*v1alpha2.Group)
|
||||
leftGroup, ok := left.(*iamv1beta1.Group)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightGroup, ok := right.(*v1alpha2.Group)
|
||||
rightGroup, ok := right.(*iamv1beta1.Group)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -70,7 +60,7 @@ func (d *groupGetter) compare(left runtime.Object, right runtime.Object, field q
|
||||
}
|
||||
|
||||
func (d *groupGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
group, ok := object.(*v1alpha2.Group)
|
||||
group, ok := object.(*iamv1beta1.Group)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 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 group
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"kubesphere.io/api/iam/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListWorkspaces(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &v1alpha2.Group{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &v1alpha2.Group{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
bar1 = &v1alpha2.Group{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
},
|
||||
}
|
||||
|
||||
groups = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, group := range groups {
|
||||
informer.Iam().V1alpha2().Groups().Informer().GetIndexer().Add(group)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,29 +1,21 @@
|
||||
/*
|
||||
Copyright 2020 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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package groupbinding
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"context"
|
||||
|
||||
"kubesphere.io/api/iam/v1alpha2"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
)
|
||||
@@ -31,40 +23,38 @@ import (
|
||||
const User = "user"
|
||||
|
||||
type groupBindingGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &groupBindingGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &groupBindingGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *groupBindingGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Iam().V1alpha2().GroupBindings().Lister().Get(name)
|
||||
groupBinding := &iamv1beta1.GroupBinding{}
|
||||
return groupBinding, d.cache.Get(context.Background(), types.NamespacedName{Name: name}, groupBinding)
|
||||
}
|
||||
|
||||
func (d *groupBindingGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
groupBindings, err := d.sharedInformers.Iam().V1alpha2().GroupBindings().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
groupBindings := &iamv1beta1.GroupBindingList{}
|
||||
if err := d.cache.List(context.Background(), groupBindings,
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, groupBinding := range groupBindings {
|
||||
result = append(result, groupBinding)
|
||||
for _, item := range groupBindings.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *groupBindingGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftGroupBinding, ok := left.(*v1alpha2.GroupBinding)
|
||||
leftGroupBinding, ok := left.(*iamv1beta1.GroupBinding)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightGroupBinding, ok := right.(*v1alpha2.GroupBinding)
|
||||
rightGroupBinding, ok := right.(*iamv1beta1.GroupBinding)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -73,16 +63,15 @@ func (d *groupBindingGetter) compare(left runtime.Object, right runtime.Object,
|
||||
}
|
||||
|
||||
func (d *groupBindingGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
groupbinding, ok := object.(*v1alpha2.GroupBinding)
|
||||
|
||||
groupBinding, ok := object.(*iamv1beta1.GroupBinding)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case User:
|
||||
return sliceutil.HasString(groupbinding.Users, string(filter.Value))
|
||||
return sliceutil.HasString(groupBinding.Users, string(filter.Value))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(groupbinding.ObjectMeta, filter)
|
||||
return v1alpha3.DefaultObjectMetaFilter(groupBinding.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 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 groupbinding
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"kubesphere.io/api/iam/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListWorkspaces(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &v1alpha2.GroupBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &v1alpha2.GroupBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
bar1 = &v1alpha2.GroupBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
},
|
||||
}
|
||||
|
||||
groupBindings = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, groupBinding := range groupBindings {
|
||||
informer.Iam().V1alpha2().GroupBindings().Informer().GetIndexer().Add(groupBinding)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
109
pkg/models/resources/v1alpha3/hpa/horizontalpodautoscalers.go
Normal file
109
pkg/models/resources/v1alpha3/hpa/horizontalpodautoscalers.go
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package hpa
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/scheme"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
)
|
||||
|
||||
type hpaGetter struct {
|
||||
cache runtimeclient.Reader
|
||||
gvk schema.GroupVersionKind
|
||||
listGVK schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func New(cache runtimeclient.Reader, k8sVersion *semver.Version) v1alpha3.Interface {
|
||||
gvk := autoscalingv2.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler")
|
||||
listGVK := schema.GroupVersionKind{
|
||||
Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
Kind: gvk.Kind + "List",
|
||||
}
|
||||
if k8sutil.ServeAutoscalingV2beta2(k8sVersion) {
|
||||
gvk.Version = "v2beta2"
|
||||
listGVK.Version = "v2beta2"
|
||||
}
|
||||
return &hpaGetter{
|
||||
cache: cache,
|
||||
gvk: gvk,
|
||||
listGVK: listGVK,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *hpaGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
obj, err := scheme.Scheme.New(s.gvk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hpa := obj.(client.Object)
|
||||
return hpa, s.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, hpa)
|
||||
}
|
||||
|
||||
func (s *hpaGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
listObj := &unstructured.UnstructuredList{}
|
||||
listObj.SetGroupVersionKind(s.listGVK)
|
||||
|
||||
if err := s.cache.List(context.Background(), listObj, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
if err := listObj.EachListItem(func(object runtime.Object) error {
|
||||
result = append(result, object)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, s.compare, s.filter), nil
|
||||
}
|
||||
|
||||
func (s *hpaGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftHPA, ok := left.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightHPA, ok := right.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(k8sutil.GetObjectMeta(leftHPA), k8sutil.GetObjectMeta(rightHPA), field)
|
||||
}
|
||||
|
||||
func (s *hpaGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
hpa, ok := object.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
targetKind, _, _ := unstructured.NestedString(hpa.UnstructuredContent(), "spec", "scaleTargetRef", "kind")
|
||||
targetName, _, _ := unstructured.NestedString(hpa.UnstructuredContent(), "spec", "scaleTargetRef", "name")
|
||||
|
||||
switch filter.Field {
|
||||
case "targetKind":
|
||||
return targetKind == string(filter.Value)
|
||||
case "targetName":
|
||||
return targetName == string(filter.Value)
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(k8sutil.GetObjectMeta(hpa), filter)
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,18 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package ingress
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -27,34 +20,32 @@ import (
|
||||
)
|
||||
|
||||
type ingressGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &ingressGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &ingressGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (g *ingressGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return g.sharedInformers.Networking().V1().Ingresses().Lister().Ingresses(namespace).Get(name)
|
||||
ingress := &v1.Ingress{}
|
||||
return ingress, g.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, ingress)
|
||||
}
|
||||
|
||||
func (g *ingressGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
// first retrieves all deployments within given namespace
|
||||
ingresses, err := g.sharedInformers.Networking().V1().Ingresses().Lister().Ingresses(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
ingresses := &v1.IngressList{}
|
||||
if err := g.cache.List(context.Background(), ingresses, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, ingress := range ingresses {
|
||||
result = append(result, ingress)
|
||||
for _, item := range ingresses.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, g.compare, g.filter), nil
|
||||
}
|
||||
|
||||
func (g *ingressGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftIngress, ok := left.(*v1.Ingress)
|
||||
if !ok {
|
||||
return false
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package ingress
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
v1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListIngresses(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &v1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &v1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
bar1 = &v1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
|
||||
ingresses = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, ingress := range ingresses {
|
||||
informer.Networking().V1().Ingresses().Informer().GetIndexer().Add(ingress)
|
||||
}
|
||||
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,18 +1,7 @@
|
||||
/*
|
||||
Copyright 2020 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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package v1alpha3
|
||||
|
||||
@@ -20,14 +9,16 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
@@ -38,7 +29,7 @@ type Interface interface {
|
||||
List(namespace string, query *query.Query) (*api.ListResult, error)
|
||||
}
|
||||
|
||||
// CompareFunc return true is left great than right
|
||||
// CompareFunc return true is left greater than right
|
||||
type CompareFunc func(runtime.Object, runtime.Object, query.Field) bool
|
||||
|
||||
type FilterFunc func(runtime.Object, query.Filter) bool
|
||||
@@ -47,7 +38,7 @@ type TransformFunc func(runtime.Object) runtime.Object
|
||||
|
||||
func DefaultList(objects []runtime.Object, q *query.Query, compareFunc CompareFunc, filterFunc FilterFunc, transformFuncs ...TransformFunc) *api.ListResult {
|
||||
// selected matched ones
|
||||
var filtered []runtime.Object
|
||||
filtered := make([]runtime.Object, 0)
|
||||
for _, object := range objects {
|
||||
selected := true
|
||||
for field, value := range q.Filters {
|
||||
@@ -83,11 +74,11 @@ func DefaultList(objects []runtime.Object, q *query.Query, compareFunc CompareFu
|
||||
|
||||
return &api.ListResult{
|
||||
TotalItems: len(filtered),
|
||||
Items: objectsToInterfaces(filtered[start:end]),
|
||||
Items: filtered[start:end],
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultObjectMetaCompare return true is left great than right
|
||||
// DefaultObjectMetaCompare return true is left greater than right
|
||||
func DefaultObjectMetaCompare(left, right metav1.ObjectMeta, sortBy query.Field) bool {
|
||||
switch sortBy {
|
||||
// ?sortBy=name
|
||||
@@ -107,7 +98,7 @@ func DefaultObjectMetaCompare(left, right metav1.ObjectMeta, sortBy query.Field)
|
||||
}
|
||||
}
|
||||
|
||||
// Default metadata filter
|
||||
// DefaultObjectMetaFilter is default metadata filter
|
||||
func DefaultObjectMetaFilter(item metav1.ObjectMeta, filter query.Filter) bool {
|
||||
switch filter.Field {
|
||||
case query.FieldNames:
|
||||
@@ -119,20 +110,18 @@ func DefaultObjectMetaFilter(item metav1.ObjectMeta, filter query.Filter) bool {
|
||||
return false
|
||||
// /namespaces?page=1&limit=10&name=default
|
||||
case query.FieldName:
|
||||
return strings.Contains(item.Name, string(filter.Value))
|
||||
// /clusters?page=1&limit=10&alias=xxx
|
||||
case query.FieldAlias:
|
||||
if item.Annotations == nil {
|
||||
return false
|
||||
displayName := item.GetAnnotations()[constants.DisplayNameAnnotationKey]
|
||||
if displayName != "" && strings.Contains(displayName, string(filter.Value)) {
|
||||
return true
|
||||
}
|
||||
return strings.Contains(item.Annotations[constants.DisplayNameAnnotationKey], string(filter.Value))
|
||||
// /namespaces?page=1&limit=10&uid=a8a8d6cf-f6a5-4fea-9c1b-e57610115706
|
||||
return strings.Contains(item.GetName(), string(filter.Value))
|
||||
// /namespaces?page=1&limit=10&uid=a8a8d6cf-f6a5-4fea-9c1b-e57610115706
|
||||
case query.FieldUID:
|
||||
return strings.Compare(string(item.UID), string(filter.Value)) == 0
|
||||
// /deployments?page=1&limit=10&namespace=kubesphere-system
|
||||
// /deployments?page=1&limit=10&namespace=kubesphere-system
|
||||
case query.FieldNamespace:
|
||||
return strings.Compare(item.Namespace, string(filter.Value)) == 0
|
||||
// /namespaces?page=1&limit=10&ownerReference=a8a8d6cf-f6a5-4fea-9c1b-e57610115706
|
||||
// /namespaces?page=1&limit=10&ownerReference=a8a8d6cf-f6a5-4fea-9c1b-e57610115706
|
||||
case query.FieldOwnerReference:
|
||||
for _, ownerReference := range item.OwnerReferences {
|
||||
if strings.Compare(string(ownerReference.UID), string(filter.Value)) == 0 {
|
||||
@@ -140,7 +129,7 @@ func DefaultObjectMetaFilter(item metav1.ObjectMeta, filter query.Filter) bool {
|
||||
}
|
||||
}
|
||||
return false
|
||||
// /namespaces?page=1&limit=10&ownerKind=Workspace
|
||||
// /namespaces?page=1&limit=10&ownerKind=Workspace
|
||||
case query.FieldOwnerKind:
|
||||
for _, ownerReference := range item.OwnerReferences {
|
||||
if strings.Compare(ownerReference.Kind, string(filter.Value)) == 0 {
|
||||
@@ -148,14 +137,15 @@ func DefaultObjectMetaFilter(item metav1.ObjectMeta, filter query.Filter) bool {
|
||||
}
|
||||
}
|
||||
return false
|
||||
// /namespaces?page=1&limit=10&annotation=openpitrix_runtime
|
||||
// /namespaces?page=1&limit=10&annotation=openpitrix_runtime
|
||||
case query.FieldAnnotation:
|
||||
return labelMatch(item.Annotations, string(filter.Value))
|
||||
// /namespaces?page=1&limit=10&label=kubesphere.io/workspace:system-workspace
|
||||
// /namespaces?page=1&limit=10&label=kubesphere.io/workspace:system-workspace
|
||||
case query.FieldLabel:
|
||||
return labelMatch(item.Labels, string(filter.Value))
|
||||
// not supported filter
|
||||
default:
|
||||
return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,11 +157,3 @@ func labelMatch(m map[string]string, filter string) bool {
|
||||
}
|
||||
return labelSelector.Matches(labels.Set(m))
|
||||
}
|
||||
|
||||
func objectsToInterfaces(objs []runtime.Object) []interface{} {
|
||||
res := make([]interface{}, 0)
|
||||
for _, obj := range objs {
|
||||
res = append(res, obj)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
/*
|
||||
|
||||
Copyright 2020 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.
|
||||
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package v1alpha3
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 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 ippool
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
k8sinformers "k8s.io/client-go/informers"
|
||||
|
||||
networkv1alpha1 "kubesphere.io/api/network/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type ippoolGetter struct {
|
||||
informers informers.SharedInformerFactory
|
||||
k8sInformers k8sinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informers informers.SharedInformerFactory, k8sInformers k8sinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &ippoolGetter{
|
||||
informers: informers,
|
||||
k8sInformers: k8sInformers,
|
||||
}
|
||||
}
|
||||
|
||||
func (n ippoolGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return n.informers.Network().V1alpha1().IPPools().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (n ippoolGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
var result []runtime.Object
|
||||
|
||||
if namespace != "" {
|
||||
workspace := ""
|
||||
ns, err := n.k8sInformers.Core().V1().Namespaces().Lister().Get(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ns.Labels != nil {
|
||||
workspace = ns.Labels[constants.WorkspaceLabelKey]
|
||||
}
|
||||
ps, err := n.informers.Network().V1alpha1().IPPools().Lister().List(labels.SelectorFromSet(
|
||||
map[string]string{
|
||||
networkv1alpha1.IPPoolDefaultLabel: "",
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range ps {
|
||||
result = append(result, p)
|
||||
}
|
||||
if workspace != "" {
|
||||
query.LabelSelector = labels.SelectorFromSet(
|
||||
map[string]string{
|
||||
constants.WorkspaceLabelKey: workspace,
|
||||
}).String()
|
||||
ps, err := n.informers.Network().V1alpha1().IPPools().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range ps {
|
||||
result = append(result, p)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ps, err := n.informers.Network().V1alpha1().IPPools().Lister().List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range ps {
|
||||
result = append(result, p)
|
||||
}
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, n.compare, n.filter), nil
|
||||
}
|
||||
|
||||
func (n ippoolGetter) filter(item runtime.Object, filter query.Filter) bool {
|
||||
p, ok := item.(*networkv1alpha1.IPPool)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(p.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func (n ippoolGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftP, ok := left.(*networkv1alpha1.IPPool)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightP, ok := right.(*networkv1alpha1.IPPool)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftP.ObjectMeta, rightP.ObjectMeta, field)
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package ippool
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8sinformers "k8s.io/client-go/informers"
|
||||
k8sfake "k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"kubesphere.io/api/network/v1alpha1"
|
||||
tenantv1alpha1 "kubesphere.io/api/tenant/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListIPPools(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldName: query.Value("foo2"),
|
||||
},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{foo2},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"test namespace filter",
|
||||
"ns1",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{foo1},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &v1alpha1.IPPool{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Labels: map[string]string{
|
||||
constants.WorkspaceLabelKey: "wk1",
|
||||
},
|
||||
},
|
||||
}
|
||||
foo2 = &v1alpha1.IPPool{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
foo3 = &v1alpha1.IPPool{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo3",
|
||||
},
|
||||
}
|
||||
ns = &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns1",
|
||||
Labels: map[string]string{
|
||||
constants.WorkspaceLabelKey: "wk1",
|
||||
},
|
||||
},
|
||||
}
|
||||
wk = &tenantv1alpha1.Workspace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "wk1",
|
||||
},
|
||||
}
|
||||
ps = []interface{}{foo1, foo2, foo3}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
|
||||
client := fake.NewSimpleClientset()
|
||||
k8sClient := k8sfake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
k8sInformer := k8sinformers.NewSharedInformerFactory(k8sClient, 0)
|
||||
|
||||
for _, p := range ps {
|
||||
informer.Network().V1alpha1().IPPools().Informer().GetIndexer().Add(p)
|
||||
}
|
||||
|
||||
informer.Tenant().V1alpha1().Workspaces().Informer().GetIndexer().Add(wk)
|
||||
k8sInformer.Core().V1().Namespaces().Informer().GetIndexer().Add(ns)
|
||||
|
||||
return New(informer, k8sInformer)
|
||||
}
|
||||
@@ -1,29 +1,22 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package job
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -37,33 +30,32 @@ const (
|
||||
)
|
||||
|
||||
type jobsGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &jobsGetter{sharedInformers: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &jobsGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *jobsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Batch().V1().Jobs().Lister().Jobs(namespace).Get(name)
|
||||
job := &batchv1.Job{}
|
||||
return job, d.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, job)
|
||||
}
|
||||
|
||||
func (d *jobsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
jobs, err := d.sharedInformers.Batch().V1().Jobs().Lister().Jobs(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
jobs := &batchv1.JobList{}
|
||||
if err := d.cache.List(context.Background(), jobs, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, job := range jobs {
|
||||
result = append(result, job)
|
||||
for _, item := range jobs.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *jobsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftJob, ok := left.(*batchv1.Job)
|
||||
if !ok {
|
||||
return false
|
||||
@@ -108,7 +100,6 @@ func jobStatus(status batchv1.JobStatus) string {
|
||||
return jobFailed
|
||||
}
|
||||
}
|
||||
|
||||
return jobRunning
|
||||
}
|
||||
|
||||
|
||||
75
pkg/models/resources/v1alpha3/label/label.go
Normal file
75
pkg/models/resources/v1alpha3/label/label.go
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package label
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type labelsGetter struct {
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &labelsGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (n labelsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
label := &clusterv1alpha1.Label{}
|
||||
return label, n.cache.Get(context.Background(), types.NamespacedName{Name: name}, label)
|
||||
}
|
||||
|
||||
func (n labelsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
labels := &clusterv1alpha1.LabelList{}
|
||||
if err := n.cache.List(context.Background(), labels, client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, item := range labels.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, n.compare, n.filter), nil
|
||||
}
|
||||
|
||||
func (n labelsGetter) filter(item runtime.Object, filter query.Filter) bool {
|
||||
label, ok := item.(*clusterv1alpha1.Label)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldName:
|
||||
return strings.Contains(label.Spec.Key, string(filter.Value)) || strings.Contains(label.Spec.Value, string(filter.Value))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (n labelsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftLabel, ok := left.(*clusterv1alpha1.Label)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightLabel, ok := right.(*clusterv1alpha1.Label)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftLabel.ObjectMeta, rightLabel.ObjectMeta, field)
|
||||
}
|
||||
@@ -1,79 +1,68 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package loginrecord
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"context"
|
||||
|
||||
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
const recordType = "type"
|
||||
|
||||
type loginrecordsGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
type loginRecordsGetter struct {
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(ksinformer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &loginrecordsGetter{ksInformer: ksinformer}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &loginRecordsGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (d *loginrecordsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.ksInformer.Iam().V1alpha2().Users().Lister().Get(name)
|
||||
func (d *loginRecordsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
loginRecord := &iamv1beta1.LoginRecord{}
|
||||
return loginRecord, d.cache.Get(context.Background(), types.NamespacedName{Name: name}, loginRecord)
|
||||
}
|
||||
|
||||
func (d *loginrecordsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
records, err := d.ksInformer.Iam().V1alpha2().LoginRecords().Lister().List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
func (d *loginRecordsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
loginRecords := &iamv1beta1.LoginRecordList{}
|
||||
if err := d.cache.List(context.Background(), loginRecords,
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, user := range records {
|
||||
result = append(result, user)
|
||||
for _, item := range loginRecords.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *loginrecordsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftUser, ok := left.(*iamv1alpha2.LoginRecord)
|
||||
func (d *loginRecordsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftRecord, ok := left.(*iamv1beta1.LoginRecord)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightUser, ok := right.(*iamv1alpha2.LoginRecord)
|
||||
rightRecord, ok := right.(*iamv1beta1.LoginRecord)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftUser.ObjectMeta, rightUser.ObjectMeta, field)
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRecord.ObjectMeta, rightRecord.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *loginrecordsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
record, ok := object.(*iamv1alpha2.LoginRecord)
|
||||
func (d *loginRecordsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
record, ok := object.(*iamv1beta1.LoginRecord)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package loginrecord
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListLoginRecords(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &iamv1alpha2.LoginRecord{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &iamv1alpha2.LoginRecord{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
bar1 = &iamv1alpha2.LoginRecord{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
},
|
||||
}
|
||||
|
||||
records = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, record := range records {
|
||||
informer.Iam().V1alpha2().LoginRecords().Informer().GetIndexer().Add(record)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,27 +1,19 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package namespace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -29,33 +21,32 @@ import (
|
||||
)
|
||||
|
||||
type namespacesGetter struct {
|
||||
informers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(informers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &namespacesGetter{informers: informers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &namespacesGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (n namespacesGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return n.informers.Core().V1().Namespaces().Lister().Get(name)
|
||||
namespace := &corev1.Namespace{}
|
||||
return namespace, n.cache.Get(context.Background(), types.NamespacedName{Name: name}, namespace)
|
||||
}
|
||||
|
||||
func (n namespacesGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
ns, err := n.informers.Core().V1().Namespaces().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
namespaces := &corev1.NamespaceList{}
|
||||
if err := n.cache.List(context.Background(), namespaces, client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, item := range ns {
|
||||
result = append(result, item)
|
||||
for _, item := range namespaces.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, n.compare, n.filter), nil
|
||||
}
|
||||
|
||||
func (n namespacesGetter) filter(item runtime.Object, filter query.Filter) bool {
|
||||
namespace, ok := item.(*v1.Namespace)
|
||||
namespace, ok := item.(*corev1.Namespace)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -68,12 +59,12 @@ func (n namespacesGetter) filter(item runtime.Object, filter query.Filter) bool
|
||||
}
|
||||
|
||||
func (n namespacesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftNs, ok := left.(*v1.Namespace)
|
||||
leftNs, ok := left.(*corev1.Namespace)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightNs, ok := right.(*v1.Namespace)
|
||||
rightNs, ok := right.(*corev1.Namespace)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package namespace
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package networkpolicy
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type networkpolicyGetter struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &networkpolicyGetter{informers: informers}
|
||||
}
|
||||
|
||||
func (n networkpolicyGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return n.informers.Networking().V1().NetworkPolicies().Lister().NetworkPolicies(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (n networkpolicyGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
nps, err := n.informers.Networking().V1().NetworkPolicies().Lister().NetworkPolicies(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, item := range nps {
|
||||
result = append(result, item)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, n.compare, n.filter), nil
|
||||
}
|
||||
|
||||
func (n networkpolicyGetter) filter(item runtime.Object, filter query.Filter) bool {
|
||||
np, ok := item.(*v1.NetworkPolicy)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(np.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func (n networkpolicyGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftNP, ok := left.(*v1.NetworkPolicy)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightNP, ok := right.(*v1.NetworkPolicy)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftNP.ObjectMeta, rightNP.ObjectMeta, field)
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package networkpolicy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
netv1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListNetworkPolicies(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldNamespace: query.Value("default"),
|
||||
},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{foo3, foo2, foo1},
|
||||
TotalItems: len(networkpolicies),
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &netv1.NetworkPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
foo2 = &netv1.NetworkPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
foo3 = &netv1.NetworkPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo3",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
networkpolicies = []interface{}{foo1, foo2, foo3}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, networkpolicy := range networkpolicies {
|
||||
informer.Networking().V1().NetworkPolicies().Informer().GetIndexer().Add(networkpolicy)
|
||||
}
|
||||
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,31 +1,18 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"context"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
resourceheper "k8s.io/kubectl/pkg/util/resource"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -34,123 +21,54 @@ import (
|
||||
|
||||
// Those annotations were added to node only for display purposes
|
||||
const (
|
||||
nodeCPURequests = "node.kubesphere.io/cpu-requests"
|
||||
nodeMemoryRequests = "node.kubesphere.io/memory-requests"
|
||||
nodeCPULimits = "node.kubesphere.io/cpu-limits"
|
||||
nodeMemoryLimits = "node.kubesphere.io/memory-limits"
|
||||
nodeCPURequestsFraction = "node.kubesphere.io/cpu-requests-fraction"
|
||||
nodeCPULimitsFraction = "node.kubesphere.io/cpu-limits-fraction"
|
||||
nodeMemoryRequestsFraction = "node.kubesphere.io/memory-requests-fraction"
|
||||
nodeMemoryLimitsFraction = "node.kubesphere.io/memory-limits-fraction"
|
||||
nodeConfigOK v1.NodeConditionType = "ConfigOK"
|
||||
nodeKubeletReady v1.NodeConditionType = "KubeletReady"
|
||||
statusRunning = "running"
|
||||
statusWarning = "warning"
|
||||
statusUnschedulable = "unschedulable"
|
||||
nodeCPURequests = "node.kubesphere.io/cpu-requests"
|
||||
nodeMemoryRequests = "node.kubesphere.io/memory-requests"
|
||||
nodeCPULimits = "node.kubesphere.io/cpu-limits"
|
||||
nodeMemoryLimits = "node.kubesphere.io/memory-limits"
|
||||
nodeCPURequestsFraction = "node.kubesphere.io/cpu-requests-fraction"
|
||||
nodeCPULimitsFraction = "node.kubesphere.io/cpu-limits-fraction"
|
||||
nodeMemoryRequestsFraction = "node.kubesphere.io/memory-requests-fraction"
|
||||
nodeMemoryLimitsFraction = "node.kubesphere.io/memory-limits-fraction"
|
||||
nodeConfigOK corev1.NodeConditionType = "ConfigOK"
|
||||
nodeKubeletReady corev1.NodeConditionType = "KubeletReady"
|
||||
statusRunning = "running"
|
||||
statusWarning = "warning"
|
||||
statusUnschedulable = "unschedulable"
|
||||
)
|
||||
|
||||
type nodesGetter struct {
|
||||
informers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(informers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &nodesGetter{
|
||||
informers: informers,
|
||||
}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &nodesGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (c *nodesGetter) Get(_, name string) (runtime.Object, error) {
|
||||
node, err := c.informers.Core().V1().Nodes().Lister().Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ignore the error, skip annotating process if error happened
|
||||
pods, _ := c.informers.Core().V1().Pods().Lister().Pods("").List(labels.Everything())
|
||||
|
||||
// Never mutate original objects!
|
||||
// Caches are shared across controllers,
|
||||
// this means that if you mutate your "copy" (actually a reference or shallow copy) of an object,
|
||||
// you'll mess up other controllers (not just your own).
|
||||
// Also, if the mutated field is a map,
|
||||
// a "concurrent map (read &) write" panic might occur,
|
||||
// causing the ks-apiserver to crash.
|
||||
// Refer:
|
||||
// https://github.com/kubesphere/kubesphere/issues/4357
|
||||
// https://github.com/kubesphere/kubesphere/issues/3469
|
||||
// https://github.com/kubesphere/kubesphere/pull/4599
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/controllers.md
|
||||
node = node.DeepCopy()
|
||||
c.annotateNode(node, pods)
|
||||
|
||||
return node, nil
|
||||
node := &corev1.Node{}
|
||||
return node, c.cache.Get(context.Background(), types.NamespacedName{Name: name}, node)
|
||||
}
|
||||
|
||||
func (c *nodesGetter) List(_ string, q *query.Query) (*api.ListResult, error) {
|
||||
nodes, err := c.informers.Core().V1().Nodes().Lister().List(q.Selector())
|
||||
if err != nil {
|
||||
nodes := &corev1.NodeList{}
|
||||
if err := c.cache.List(context.Background(), nodes,
|
||||
client.MatchingLabelsSelector{Selector: q.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var filtered []*v1.Node
|
||||
for _, object := range nodes {
|
||||
selected := true
|
||||
for field, value := range q.Filters {
|
||||
if !c.filter(object, query.Filter{Field: field, Value: value}) {
|
||||
selected = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if selected {
|
||||
filtered = append(filtered, object)
|
||||
}
|
||||
var result []runtime.Object
|
||||
for _, item := range nodes.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
|
||||
// sort by sortBy field
|
||||
sort.Slice(filtered, func(i, j int) bool {
|
||||
if !q.Ascending {
|
||||
return c.compare(filtered[i], filtered[j], q.SortBy)
|
||||
}
|
||||
return !c.compare(filtered[i], filtered[j], q.SortBy)
|
||||
})
|
||||
|
||||
total := len(filtered)
|
||||
if q.Pagination == nil {
|
||||
q.Pagination = query.NoPagination
|
||||
}
|
||||
start, end := q.Pagination.GetValidPagination(total)
|
||||
selectedNodes := filtered[start:end]
|
||||
|
||||
// ignore the error, skip annotating process if error happened
|
||||
pods, _ := c.informers.Core().V1().Pods().Lister().Pods("").List(labels.Everything())
|
||||
var nonTerminatedPodsList []*v1.Pod
|
||||
for _, pod := range pods {
|
||||
if pod.Status.Phase != v1.PodSucceeded && pod.Status.Phase != v1.PodFailed {
|
||||
nonTerminatedPodsList = append(nonTerminatedPodsList, pod)
|
||||
}
|
||||
}
|
||||
|
||||
var result = make([]interface{}, 0)
|
||||
for _, node := range selectedNodes {
|
||||
node = node.DeepCopy()
|
||||
c.annotateNode(node, nonTerminatedPodsList)
|
||||
result = append(result, node)
|
||||
}
|
||||
|
||||
return &api.ListResult{
|
||||
TotalItems: total,
|
||||
Items: result,
|
||||
}, nil
|
||||
return v1alpha3.DefaultList(result, q, c.compare, c.filter), nil
|
||||
}
|
||||
|
||||
func (c *nodesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
leftNode, ok := left.(*v1.Node)
|
||||
leftNode, ok := left.(*corev1.Node)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightNode, ok := right.(*v1.Node)
|
||||
rightNode, ok := right.(*corev1.Node)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -159,7 +77,7 @@ func (c *nodesGetter) compare(left runtime.Object, right runtime.Object, field q
|
||||
}
|
||||
|
||||
func (c *nodesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
node, ok := object.(*v1.Node)
|
||||
node, ok := object.(*corev1.Node)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -167,80 +85,10 @@ func (c *nodesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
case query.FieldStatus:
|
||||
return getNodeStatus(node) == string(filter.Value)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(node.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
// annotateNode adds cpu/memory requests usage data to node's annotations
|
||||
// this operation mutates the *v1.Node passed in
|
||||
// so DO A DEEPCOPY before calling
|
||||
func (c *nodesGetter) annotateNode(node *v1.Node, pods []*v1.Pod) {
|
||||
if node.Annotations == nil {
|
||||
node.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
if len(pods) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var nodePods []*v1.Pod
|
||||
for _, pod := range pods {
|
||||
if pod.Spec.NodeName == node.Name {
|
||||
nodePods = append(nodePods, pod)
|
||||
}
|
||||
}
|
||||
|
||||
reqs, limits := c.getPodsTotalRequestAndLimits(nodePods)
|
||||
|
||||
cpuReqs, cpuLimits, memoryReqs, memoryLimits := reqs[v1.ResourceCPU], limits[v1.ResourceCPU], reqs[v1.ResourceMemory], limits[v1.ResourceMemory]
|
||||
node.Annotations[nodeCPURequests] = cpuReqs.String()
|
||||
node.Annotations[nodeCPULimits] = cpuLimits.String()
|
||||
node.Annotations[nodeMemoryRequests] = memoryReqs.String()
|
||||
node.Annotations[nodeMemoryLimits] = memoryLimits.String()
|
||||
|
||||
fractionCpuReqs, fractionCpuLimits := float64(0), float64(0)
|
||||
allocatable := node.Status.Allocatable
|
||||
if allocatable.Cpu().MilliValue() != 0 {
|
||||
fractionCpuReqs = float64(cpuReqs.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
|
||||
fractionCpuLimits = float64(cpuLimits.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
|
||||
}
|
||||
fractionMemoryReqs, fractionMemoryLimits := float64(0), float64(0)
|
||||
if allocatable.Memory().Value() != 0 {
|
||||
fractionMemoryReqs = float64(memoryReqs.Value()) / float64(allocatable.Memory().Value()) * 100
|
||||
fractionMemoryLimits = float64(memoryLimits.Value()) / float64(allocatable.Memory().Value()) * 100
|
||||
}
|
||||
|
||||
node.Annotations[nodeCPURequestsFraction] = fmt.Sprintf("%d%%", int(fractionCpuReqs))
|
||||
node.Annotations[nodeCPULimitsFraction] = fmt.Sprintf("%d%%", int(fractionCpuLimits))
|
||||
node.Annotations[nodeMemoryRequestsFraction] = fmt.Sprintf("%d%%", int(fractionMemoryReqs))
|
||||
node.Annotations[nodeMemoryLimitsFraction] = fmt.Sprintf("%d%%", int(fractionMemoryLimits))
|
||||
}
|
||||
|
||||
func (c *nodesGetter) getPodsTotalRequestAndLimits(pods []*v1.Pod) (reqs map[v1.ResourceName]resource.Quantity, limits map[v1.ResourceName]resource.Quantity) {
|
||||
reqs, limits = map[v1.ResourceName]resource.Quantity{}, map[v1.ResourceName]resource.Quantity{}
|
||||
for _, pod := range pods {
|
||||
podReqs, podLimits := resourceheper.PodRequestsAndLimits(pod)
|
||||
for podReqName, podReqValue := range podReqs {
|
||||
if value, ok := reqs[podReqName]; !ok {
|
||||
reqs[podReqName] = podReqValue.DeepCopy()
|
||||
} else {
|
||||
value.Add(podReqValue)
|
||||
reqs[podReqName] = value
|
||||
}
|
||||
}
|
||||
for podLimitName, podLimitValue := range podLimits {
|
||||
if value, ok := limits[podLimitName]; !ok {
|
||||
limits[podLimitName] = podLimitValue.DeepCopy()
|
||||
} else {
|
||||
value.Add(podLimitValue)
|
||||
limits[podLimitName] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getNodeStatus(node *v1.Node) string {
|
||||
func getNodeStatus(node *corev1.Node) string {
|
||||
if node.Spec.Unschedulable {
|
||||
return statusUnschedulable
|
||||
}
|
||||
@@ -253,17 +101,17 @@ func getNodeStatus(node *v1.Node) string {
|
||||
return statusRunning
|
||||
}
|
||||
|
||||
var expectedConditions = map[v1.NodeConditionType]v1.ConditionStatus{
|
||||
v1.NodeMemoryPressure: v1.ConditionFalse,
|
||||
v1.NodeDiskPressure: v1.ConditionFalse,
|
||||
v1.NodePIDPressure: v1.ConditionFalse,
|
||||
v1.NodeNetworkUnavailable: v1.ConditionFalse,
|
||||
nodeConfigOK: v1.ConditionTrue,
|
||||
nodeKubeletReady: v1.ConditionTrue,
|
||||
v1.NodeReady: v1.ConditionTrue,
|
||||
var expectedConditions = map[corev1.NodeConditionType]corev1.ConditionStatus{
|
||||
corev1.NodeMemoryPressure: corev1.ConditionFalse,
|
||||
corev1.NodeDiskPressure: corev1.ConditionFalse,
|
||||
corev1.NodePIDPressure: corev1.ConditionFalse,
|
||||
corev1.NodeNetworkUnavailable: corev1.ConditionFalse,
|
||||
nodeConfigOK: corev1.ConditionTrue,
|
||||
nodeKubeletReady: corev1.ConditionTrue,
|
||||
corev1.NodeReady: corev1.ConditionTrue,
|
||||
}
|
||||
|
||||
func isUnhealthyStatus(condition v1.NodeCondition) bool {
|
||||
func isUnhealthyStatus(condition corev1.NodeCondition) bool {
|
||||
expectedStatus := expectedConditions[condition.Type]
|
||||
if expectedStatus != "" && condition.Status != expectedStatus {
|
||||
return true
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package node
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
// mergeResourceLists will merge resoure lists. When two lists have the same resourece, the value from
|
||||
// the last list will be present in the result
|
||||
func mergeResourceLists(resourceLists ...corev1.ResourceList) corev1.ResourceList {
|
||||
result := corev1.ResourceList{}
|
||||
for _, rl := range resourceLists {
|
||||
for resource, quantity := range rl {
|
||||
result[resource] = quantity
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func getResourceList(cpu, memory string) corev1.ResourceList {
|
||||
res := corev1.ResourceList{}
|
||||
if cpu != "" {
|
||||
res[corev1.ResourceCPU] = resource.MustParse(cpu)
|
||||
}
|
||||
if memory != "" {
|
||||
res[corev1.ResourceMemory] = resource.MustParse(memory)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
var nodeAllocatable = mergeResourceLists(getResourceList("4", "12Gi"))
|
||||
var node = &corev1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Status: corev1.NodeStatus{
|
||||
Allocatable: nodeAllocatable,
|
||||
},
|
||||
}
|
||||
|
||||
var pods = []*corev1.Pod{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "foo",
|
||||
Name: "pod-with-resources",
|
||||
},
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Pod",
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: node.Name,
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "cpu-mem",
|
||||
Image: "image:latest",
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: getResourceList("1", "1Gi"),
|
||||
Limits: getResourceList("2", "2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: corev1.PodStatus{
|
||||
Phase: corev1.PodRunning,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "foo2",
|
||||
Name: "pod-with-resources",
|
||||
},
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Pod",
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: node.Name,
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "cpu-mem",
|
||||
Image: "image:latest",
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: getResourceList("1", "1Gi"),
|
||||
Limits: getResourceList("2", "2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: corev1.PodStatus{
|
||||
Phase: corev1.PodRunning,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var expectedAnnotations = map[string]string{
|
||||
nodeCPURequests: "2",
|
||||
nodeCPULimits: "4",
|
||||
nodeCPURequestsFraction: "50%",
|
||||
nodeCPULimitsFraction: "100%",
|
||||
nodeMemoryRequests: "2Gi",
|
||||
nodeMemoryLimits: "4Gi",
|
||||
nodeMemoryRequestsFraction: "16%",
|
||||
nodeMemoryLimitsFraction: "33%",
|
||||
}
|
||||
|
||||
func TestNodesGetterGet(t *testing.T) {
|
||||
fake := fake.NewSimpleClientset(node, pods[0], pods[1])
|
||||
|
||||
informer := informers.NewSharedInformerFactory(fake, 0)
|
||||
informer.Core().V1().Nodes().Informer().GetIndexer().Add(node)
|
||||
for _, pod := range pods {
|
||||
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod)
|
||||
}
|
||||
|
||||
nodeGetter := New(informer)
|
||||
got, err := nodeGetter.Get("", node.Name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
nodeGot := got.(*corev1.Node)
|
||||
|
||||
if diff := cmp.Diff(nodeGot.Annotations, expectedAnnotations); len(diff) != 0 {
|
||||
t.Errorf("%T, diff(-got, +expected), %v", expectedAnnotations, nodeGot.Annotations)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestListNodes(t *testing.T) {
|
||||
tests := []struct {
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
}{
|
||||
{
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value(node2.Name)},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
node2Expected,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldStatus: query.Value(statusUnschedulable)},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
node1Expected,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldStatus: query.Value(statusRunning)},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
node2Expected,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for index, test := range tests {
|
||||
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
||||
|
||||
got, err := getter.List("", test.query)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
node1 = &corev1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
},
|
||||
Spec: corev1.NodeSpec{
|
||||
Unschedulable: true,
|
||||
},
|
||||
}
|
||||
|
||||
node1Expected = &corev1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node1",
|
||||
Annotations: map[string]string{},
|
||||
},
|
||||
Spec: corev1.NodeSpec{
|
||||
Unschedulable: true,
|
||||
},
|
||||
}
|
||||
|
||||
node2 = &corev1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node2",
|
||||
},
|
||||
Spec: corev1.NodeSpec{
|
||||
Unschedulable: false,
|
||||
},
|
||||
}
|
||||
|
||||
node2Expected = &corev1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node2",
|
||||
Annotations: map[string]string{},
|
||||
},
|
||||
Spec: corev1.NodeSpec{
|
||||
Unschedulable: false,
|
||||
},
|
||||
}
|
||||
|
||||
nodes = []*corev1.Node{node1, node2}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
|
||||
fake := fake.NewSimpleClientset(node1, node2)
|
||||
|
||||
informer := informers.NewSharedInformerFactory(fake, 0)
|
||||
for _, node := range nodes {
|
||||
informer.Core().V1().Nodes().Informer().GetIndexer().Add(node)
|
||||
}
|
||||
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package notification
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type notificationmanagerGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNotificationManagerGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return ¬ificationmanagerGetter{ksInformer: informer}
|
||||
}
|
||||
|
||||
func (g *notificationmanagerGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return g.ksInformer.Notification().V2beta2().NotificationManagers().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (g *notificationmanagerGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
objs, err := g.ksInformer.Notification().V2beta2().NotificationManagers().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, obj := range objs {
|
||||
result = append(result, obj)
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, compare, filter), nil
|
||||
}
|
||||
|
||||
type configGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNotificationConfigGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &configGetter{ksInformer: informer}
|
||||
}
|
||||
|
||||
func (g *configGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return g.ksInformer.Notification().V2beta2().Configs().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (g *configGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
objs, err := g.ksInformer.Notification().V2beta2().Configs().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, obj := range objs {
|
||||
result = append(result, obj)
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, compare, filter), nil
|
||||
}
|
||||
|
||||
type receiverGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNotificationReceiverGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &receiverGetter{ksInformer: informer}
|
||||
}
|
||||
|
||||
func (g *receiverGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return g.ksInformer.Notification().V2beta2().Receivers().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (g *receiverGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
objs, err := g.ksInformer.Notification().V2beta2().Receivers().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, obj := range objs {
|
||||
result = append(result, obj)
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, compare, filter), nil
|
||||
}
|
||||
|
||||
type routerGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNotificationRouterGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &routerGetter{ksInformer: informer}
|
||||
}
|
||||
|
||||
func (g *routerGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return g.ksInformer.Notification().V2beta2().Routers().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (g *routerGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
objs, err := g.ksInformer.Notification().V2beta2().Routers().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, obj := range objs {
|
||||
result = append(result, obj)
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, compare, filter), nil
|
||||
}
|
||||
|
||||
type silenceGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNotificationSilenceGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &silenceGetter{ksInformer: informer}
|
||||
}
|
||||
|
||||
func (g *silenceGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return g.ksInformer.Notification().V2beta2().Silences().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (g *silenceGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
objs, err := g.ksInformer.Notification().V2beta2().Silences().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, obj := range objs {
|
||||
result = append(result, obj)
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, compare, filter), nil
|
||||
}
|
||||
|
||||
func compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftObj, err := meta.Accessor(left)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
rightObj, err := meta.Accessor(right)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(meta.AsPartialObjectMetadata(leftObj).ObjectMeta,
|
||||
meta.AsPartialObjectMetadata(rightObj).ObjectMeta, field)
|
||||
}
|
||||
|
||||
func filter(object runtime.Object, filter query.Filter) bool {
|
||||
|
||||
accessor, err := meta.Accessor(object)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldNames:
|
||||
for _, name := range strings.Split(string(filter.Value), ",") {
|
||||
if accessor.GetName() == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
case query.FieldName:
|
||||
return strings.Contains(accessor.GetName(), string(filter.Value))
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package notification
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/uuid"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"kubesphere.io/api/notification/v2beta2"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
Prefix = "foo"
|
||||
LengthMin = 3
|
||||
LengthMax = 10
|
||||
)
|
||||
|
||||
func TestListObjects(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
key string
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
v2beta2.ResourcesPluralConfig,
|
||||
},
|
||||
{
|
||||
"test name filter",
|
||||
v2beta2.ResourcesPluralReceiver,
|
||||
},
|
||||
{
|
||||
"test name filter",
|
||||
v2beta2.ResourcesPluralRouter,
|
||||
},
|
||||
{
|
||||
"test name filter",
|
||||
v2beta2.ResourcesPluralSilence,
|
||||
},
|
||||
}
|
||||
|
||||
q := &query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: true,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value(Prefix)},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
getter, objects, err := prepare(test.key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
got, err := getter.List("", q)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := &api.ListResult{
|
||||
Items: objects,
|
||||
TotalItems: len(objects),
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, expected); diff != "" {
|
||||
t.Errorf("[%s] %T differ (-got, +want): %s", test.description, expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func prepare(key string) (v1alpha3.Interface, []interface{}, error) {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := ksinformers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
var obj runtime.Object
|
||||
var indexer cache.Indexer
|
||||
var getter func(informer ksinformers.SharedInformerFactory) v1alpha3.Interface
|
||||
switch key {
|
||||
case v2beta2.ResourcesPluralConfig:
|
||||
indexer = informer.Notification().V2beta2().Configs().Informer().GetIndexer()
|
||||
getter = NewNotificationConfigGetter
|
||||
obj = &v2beta2.Config{}
|
||||
case v2beta2.ResourcesPluralReceiver:
|
||||
indexer = informer.Notification().V2beta2().Receivers().Informer().GetIndexer()
|
||||
getter = NewNotificationReceiverGetter
|
||||
obj = &v2beta2.Receiver{}
|
||||
case v2beta2.ResourcesPluralRouter:
|
||||
indexer = informer.Notification().V2beta2().Routers().Informer().GetIndexer()
|
||||
getter = NewNotificationRouterGetter
|
||||
obj = &v2beta2.Router{}
|
||||
case v2beta2.ResourcesPluralSilence:
|
||||
indexer = informer.Notification().V2beta2().Silences().Informer().GetIndexer()
|
||||
getter = NewNotificationSilenceGetter
|
||||
obj = &v2beta2.Silence{}
|
||||
default:
|
||||
return nil, nil, errors.New("unowned type %s", key)
|
||||
}
|
||||
|
||||
num := rand.Intn(LengthMax)
|
||||
if num < LengthMin {
|
||||
num = LengthMin
|
||||
}
|
||||
|
||||
var suffix []string
|
||||
for i := 0; i < num; i++ {
|
||||
s := uuid.New().String()
|
||||
suffix = append(suffix, s)
|
||||
}
|
||||
sort.Strings(suffix)
|
||||
|
||||
var objects []interface{}
|
||||
for i := 0; i < num; i++ {
|
||||
val := obj.DeepCopyObject()
|
||||
accessor, err := meta.Accessor(val)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
accessor.SetName(Prefix + "-" + suffix[i])
|
||||
err = indexer.Add(accessor)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
objects = append(objects, val)
|
||||
}
|
||||
|
||||
return getter(informer), objects, nil
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
approvers:
|
||||
- zheng1
|
||||
- wansir
|
||||
- zryfish
|
||||
|
||||
reviewers:
|
||||
- zheng1
|
||||
- wansir
|
||||
- zryfish
|
||||
- xyz-li
|
||||
|
||||
labels:
|
||||
- area/api
|
||||
- area/app-management
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package application
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"kubesphere.io/api/application/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type helmApplicationsGetter struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informers externalversions.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &helmApplicationsGetter{
|
||||
informers: informers,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *helmApplicationsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
app, err := r.informers.Application().V1alpha1().HelmApplications().Lister().Get(name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return app, nil
|
||||
}
|
||||
|
||||
func (r *helmApplicationsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
var apps []*v1alpha1.HelmApplication
|
||||
var err error
|
||||
|
||||
apps, err = r.informers.Application().V1alpha1().HelmApplications().Lister().List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
for i := range apps {
|
||||
result = append(result, apps[i])
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, r.compare, r.filter), nil
|
||||
}
|
||||
|
||||
func (r *helmApplicationsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftApp, ok := left.(*v1alpha1.HelmApplication)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightApp, ok := right.(*v1alpha1.HelmApplication)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch field {
|
||||
case query.FieldName:
|
||||
return strings.Compare(leftApp.Spec.Name, rightApp.Spec.Name) > 0
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftApp.ObjectMeta, rightApp.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *helmApplicationsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
application, ok := object.(*v1alpha1.HelmApplication)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldName:
|
||||
return strings.Contains(application.Spec.Name, string(filter.Value))
|
||||
case query.FieldStatus:
|
||||
return strings.Contains(application.Status.State, string(filter.Value))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(application.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package applicationversion
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"kubesphere.io/api/application/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type applicationVersionsGetter struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informers externalversions.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &applicationVersionsGetter{
|
||||
informers: informers,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *applicationVersionsGetter) Get(_, name string) (runtime.Object, error) {
|
||||
app, err := r.informers.Application().V1alpha1().HelmApplicationVersions().Lister().Get(name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return app, nil
|
||||
}
|
||||
|
||||
func (r *applicationVersionsGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
var apps []*v1alpha1.HelmApplicationVersion
|
||||
var err error
|
||||
|
||||
apps, err = r.informers.Application().V1alpha1().HelmApplicationVersions().Lister().List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
for i := range apps {
|
||||
result = append(result, apps[i])
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, r.compare, r.filter), nil
|
||||
}
|
||||
|
||||
func (r *applicationVersionsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftAppVer, ok := left.(*v1alpha1.HelmApplicationVersion)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightAppVer, ok := right.(*v1alpha1.HelmApplicationVersion)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch field {
|
||||
case query.FieldName:
|
||||
return strings.Compare(leftAppVer.Spec.Name, rightAppVer.Spec.Name) > 0
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftAppVer.ObjectMeta, rightAppVer.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *applicationVersionsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
appVer, ok := object.(*v1alpha1.HelmApplicationVersion)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldName:
|
||||
return strings.Contains(appVer.Spec.Name, string(filter.Value))
|
||||
case query.FieldStatus:
|
||||
return strings.Contains(appVer.Status.State, string(filter.Value))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(appVer.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package category
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"kubesphere.io/api/application/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type helmCategoriesGetter struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informers externalversions.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &helmCategoriesGetter{
|
||||
informers: informers,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *helmCategoriesGetter) Get(_, name string) (runtime.Object, error) {
|
||||
app, err := r.informers.Application().V1alpha1().HelmCategories().Lister().Get(name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return app, nil
|
||||
}
|
||||
|
||||
func (r *helmCategoriesGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
var ctg []*v1alpha1.HelmCategory
|
||||
var err error
|
||||
|
||||
ctg, err = r.informers.Application().V1alpha1().HelmCategories().Lister().List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
for i := range ctg {
|
||||
result = append(result, ctg[i])
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, r.compare, r.filter), nil
|
||||
}
|
||||
|
||||
func (r *helmCategoriesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
ctg1, ok := left.(*v1alpha1.HelmCategory)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
ctg2, ok := right.(*v1alpha1.HelmCategory)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch field {
|
||||
case query.FieldName:
|
||||
return strings.Compare(ctg1.Spec.Name, ctg2.Spec.Name) > 0
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(ctg1.ObjectMeta, ctg2.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *helmCategoriesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
application, ok := object.(*v1alpha1.HelmCategory)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldName:
|
||||
return strings.Contains(application.Spec.Name, string(filter.Value))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(application.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package helmrelease
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"kubesphere.io/api/application/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type helmReleasesGetter struct {
|
||||
informers externalversions.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informers externalversions.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &helmReleasesGetter{
|
||||
informers: informers,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *helmReleasesGetter) Get(_, name string) (runtime.Object, error) {
|
||||
app, err := r.informers.Application().V1alpha1().HelmReleases().Lister().Get(name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return app, nil
|
||||
}
|
||||
|
||||
func (r *helmReleasesGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
var rls []*v1alpha1.HelmRelease
|
||||
var err error
|
||||
|
||||
rls, err = r.informers.Application().V1alpha1().HelmReleases().Lister().List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
for i := range rls {
|
||||
result = append(result, rls[i])
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, r.compare, r.filter), nil
|
||||
}
|
||||
|
||||
func (r *helmReleasesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftRls, ok := left.(*v1alpha1.HelmRelease)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightRls, ok := right.(*v1alpha1.HelmRelease)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch field {
|
||||
case query.FieldName:
|
||||
return strings.Compare(leftRls.Spec.Name, rightRls.Spec.Name) > 0
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRls.ObjectMeta, rightRls.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *helmReleasesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
rls, ok := object.(*v1alpha1.HelmRelease)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldName:
|
||||
return strings.Contains(rls.Spec.Name, string(filter.Value))
|
||||
case query.FieldStatus:
|
||||
return strings.Contains(rls.Status.State, string(filter.Value))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(rls.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"kubesphere.io/api/application/v1alpha1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type reposGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(ksinformer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &reposGetter{ksInformer: ksinformer}
|
||||
}
|
||||
|
||||
func (d *reposGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.ksInformer.Application().V1alpha1().HelmRepos().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (d *reposGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
var repos []*v1alpha1.HelmRepo
|
||||
var err error
|
||||
repos, err = d.ksInformer.Application().V1alpha1().HelmRepos().Lister().List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]runtime.Object, 0, len(repos))
|
||||
for _, user := range repos {
|
||||
result = append(result, user)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *reposGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
repo1, ok := left.(*v1alpha1.HelmRepo)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
repo2, ok := right.(*v1alpha1.HelmRepo)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch field {
|
||||
case query.FieldName:
|
||||
return strings.Compare(repo1.Spec.Name, repo2.Spec.Name) > 0
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(repo1.ObjectMeta, repo2.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *reposGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
repo, ok := object.(*v1alpha1.HelmRepo)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldName:
|
||||
return strings.Contains(repo.Spec.Name, string(filter.Value))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(repo.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,20 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package persistentvolume
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -33,26 +26,27 @@ const (
|
||||
)
|
||||
|
||||
type persistentVolumeGetter struct {
|
||||
informers informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(informer informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &persistentVolumeGetter{informers: informer}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &persistentVolumeGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (p *persistentVolumeGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
pv, err := p.informers.Core().V1().PersistentVolumes().Lister().Get(name)
|
||||
return pv, err
|
||||
func (p *persistentVolumeGetter) Get(_, name string) (runtime.Object, error) {
|
||||
pv := &corev1.PersistentVolume{}
|
||||
return pv, p.cache.Get(context.Background(), types.NamespacedName{Name: name}, pv)
|
||||
}
|
||||
|
||||
func (p *persistentVolumeGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
all, err := p.informers.Core().V1().PersistentVolumes().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
persistentVolumes := &corev1.PersistentVolumeList{}
|
||||
if err := p.cache.List(context.Background(), persistentVolumes, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result []runtime.Object
|
||||
for _, pv := range all {
|
||||
result = append(result, pv)
|
||||
for _, item := range persistentVolumes.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, p.compare, p.filter), nil
|
||||
}
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package persistentvolume
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
var (
|
||||
testStorageClassName = "test-csi"
|
||||
)
|
||||
|
||||
func TestListPods(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{pv3, pv2, pv1},
|
||||
TotalItems: len(persistentVolumes),
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"test status filter",
|
||||
"",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldStatus: query.Value(pv1.Status.Phase),
|
||||
},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{pv1},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("[%s] %T differ (-got, +want): %s", test.description, test.expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
pv1 = &corev1.PersistentVolume{
|
||||
TypeMeta: metav1.TypeMeta{},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pv-1",
|
||||
},
|
||||
Status: corev1.PersistentVolumeStatus{
|
||||
Phase: "bound",
|
||||
},
|
||||
}
|
||||
pv2 = &corev1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pv-2",
|
||||
},
|
||||
Status: corev1.PersistentVolumeStatus{
|
||||
Phase: "available",
|
||||
},
|
||||
Spec: corev1.PersistentVolumeSpec{
|
||||
StorageClassName: testStorageClassName,
|
||||
},
|
||||
}
|
||||
pv3 = &corev1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-3",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
|
||||
persistentVolumes = []interface{}{pv1, pv2, pv3}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, pv := range persistentVolumes {
|
||||
_ = informer.Core().V1().PersistentVolumes().Informer().GetIndexer().Add(pv)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,30 +1,20 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package persistentvolumeclaim
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
snapshotinformers "github.com/kubernetes-csi/external-snapshotter/client/v4/informers/externalversions"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -32,113 +22,67 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
storageClassName = "storageClassName"
|
||||
|
||||
storageClassName = "storageClassName"
|
||||
annotationInUse = "kubesphere.io/in-use"
|
||||
annotationAllowSnapshot = "kubesphere.io/allow-snapshot"
|
||||
annotationStorageProvisioner = "volume.beta.kubernetes.io/storage-provisioner"
|
||||
)
|
||||
|
||||
type persistentVolumeClaimGetter struct {
|
||||
informers informers.SharedInformerFactory
|
||||
snapshotInformers snapshotinformers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(informer informers.SharedInformerFactory, snapshotInformer snapshotinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &persistentVolumeClaimGetter{informers: informer, snapshotInformers: snapshotInformer}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &persistentVolumeClaimGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (p *persistentVolumeClaimGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
pvc, err := p.informers.Core().V1().PersistentVolumeClaims().Lister().PersistentVolumeClaims(namespace).Get(name)
|
||||
if err != nil {
|
||||
return pvc, err
|
||||
}
|
||||
// we should never mutate the shared objects from informers
|
||||
pvc = pvc.DeepCopy()
|
||||
p.annotatePVC(pvc)
|
||||
return pvc, nil
|
||||
pvc := &corev1.PersistentVolumeClaim{}
|
||||
return pvc, p.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, pvc)
|
||||
}
|
||||
|
||||
func (p *persistentVolumeClaimGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
all, err := p.informers.Core().V1().PersistentVolumeClaims().Lister().PersistentVolumeClaims(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
persistentVolumeClaims := &corev1.PersistentVolumeClaimList{}
|
||||
if err := p.cache.List(context.Background(), persistentVolumeClaims, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, pvc := range all {
|
||||
pvc = pvc.DeepCopy()
|
||||
p.annotatePVC(pvc)
|
||||
result = append(result, pvc)
|
||||
for _, item := range persistentVolumeClaims.Items {
|
||||
result = append(result, item.DeepCopy())
|
||||
}
|
||||
return v1alpha3.DefaultList(result, query, p.compare, p.filter), nil
|
||||
}
|
||||
|
||||
func (p *persistentVolumeClaimGetter) compare(left, right runtime.Object, field query.Field) bool {
|
||||
leftSnapshot, ok := left.(*v1.PersistentVolumeClaim)
|
||||
leftPVC, ok := left.(*corev1.PersistentVolumeClaim)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
rightSnapshot, ok := right.(*v1.PersistentVolumeClaim)
|
||||
rightPVC, ok := right.(*corev1.PersistentVolumeClaim)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftSnapshot.ObjectMeta, rightSnapshot.ObjectMeta, field)
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftPVC.ObjectMeta, rightPVC.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (p *persistentVolumeClaimGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
pvc, ok := object.(*v1.PersistentVolumeClaim)
|
||||
pvc, ok := object.(*corev1.PersistentVolumeClaim)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldStatus:
|
||||
return strings.EqualFold(string(pvc.Status.Phase), string(filter.Value))
|
||||
statuses := strings.Split(string(filter.Value), "|")
|
||||
for _, status := range statuses {
|
||||
if !strings.EqualFold(string(pvc.Status.Phase), status) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case storageClassName:
|
||||
return pvc.Spec.StorageClassName != nil && *pvc.Spec.StorageClassName == string(filter.Value)
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaFilter(pvc.ObjectMeta, filter)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *persistentVolumeClaimGetter) annotatePVC(pvc *v1.PersistentVolumeClaim) {
|
||||
inUse := p.countPods(pvc.Name, pvc.Namespace)
|
||||
isSnapshotAllow := p.isSnapshotAllowed(pvc.GetAnnotations()[annotationStorageProvisioner])
|
||||
if pvc.Annotations == nil {
|
||||
pvc.Annotations = make(map[string]string)
|
||||
}
|
||||
pvc.Annotations[annotationInUse] = strconv.FormatBool(inUse)
|
||||
pvc.Annotations[annotationAllowSnapshot] = strconv.FormatBool(isSnapshotAllow)
|
||||
}
|
||||
|
||||
func (p *persistentVolumeClaimGetter) countPods(name, namespace string) bool {
|
||||
pods, err := p.informers.Core().V1().Pods().Lister().Pods(namespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, pod := range pods {
|
||||
for _, pvc := range pod.Spec.Volumes {
|
||||
if pvc.PersistentVolumeClaim != nil && pvc.PersistentVolumeClaim.ClaimName == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *persistentVolumeClaimGetter) isSnapshotAllowed(provisioner string) bool {
|
||||
if len(provisioner) == 0 {
|
||||
return false
|
||||
}
|
||||
volumeSnapshotClasses, err := p.snapshotInformers.Snapshot().V1().VolumeSnapshotClasses().Lister().List(labels.Everything())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, volumeSnapshotClass := range volumeSnapshotClasses {
|
||||
if volumeSnapshotClass.Driver == provisioner {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package persistentvolumeclaim
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
snapshot "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
|
||||
snapshotefakeclient "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned/fake"
|
||||
snapshotinformers "github.com/kubernetes-csi/external-snapshotter/client/v4/informers/externalversions"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
var (
|
||||
testStorageClassName = "test-csi"
|
||||
)
|
||||
|
||||
func TestListPVCs(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldNamespace: query.Value("default")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{pvc3Expected, pvc2Expected, pvc1Expected},
|
||||
TotalItems: len(persistentVolumeClaims),
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"test status filter",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldNamespace: query.Value("default"),
|
||||
query.FieldStatus: query.Value(pvc1.Status.Phase),
|
||||
},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{pvc1Expected},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"test StorageClass filter and allow snapshot",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldNamespace: query.Value("default"),
|
||||
query.Field(storageClassName): query.Value(*pvc2.Spec.StorageClassName),
|
||||
},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{pvc2Expected},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"test pvc in use",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldNamespace: query.Value("default"),
|
||||
query.FieldName: query.Value(pvc3.Name),
|
||||
},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{pvc3Expected},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("[%s] %T differ (-got, +want): %s", test.description, test.expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
pvc1 = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-1",
|
||||
Namespace: "default",
|
||||
},
|
||||
Status: corev1.PersistentVolumeClaimStatus{
|
||||
Phase: corev1.ClaimPending,
|
||||
},
|
||||
}
|
||||
|
||||
pvc1Expected = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-1",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
annotationInUse: "false",
|
||||
annotationAllowSnapshot: "false",
|
||||
},
|
||||
},
|
||||
Status: corev1.PersistentVolumeClaimStatus{
|
||||
Phase: corev1.ClaimPending,
|
||||
},
|
||||
}
|
||||
|
||||
pvc2 = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-2",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
annotationStorageProvisioner: testStorageClassName,
|
||||
},
|
||||
},
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
StorageClassName: &testStorageClassName,
|
||||
},
|
||||
}
|
||||
|
||||
pvc2Expected = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-2",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
annotationInUse: "false",
|
||||
annotationAllowSnapshot: "true",
|
||||
annotationStorageProvisioner: testStorageClassName,
|
||||
},
|
||||
},
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
StorageClassName: &testStorageClassName,
|
||||
},
|
||||
}
|
||||
|
||||
pvc3 = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-3",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
|
||||
pvc3Expected = &corev1.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvc-3",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
annotationInUse: "true",
|
||||
annotationAllowSnapshot: "false",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pod1 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-1",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Volumes: []corev1.Volume{
|
||||
{
|
||||
Name: "data",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: pvc3.Name,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
volumeSnapshotClass1 = &snapshot.VolumeSnapshotClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "VolumeSnapshotClass-1",
|
||||
Namespace: "default",
|
||||
},
|
||||
Driver: testStorageClassName,
|
||||
}
|
||||
|
||||
persistentVolumeClaims = []interface{}{pvc1, pvc2, pvc3}
|
||||
pods = []interface{}{pod1}
|
||||
volumeSnapshotClasses = []interface{}{volumeSnapshotClass1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
snapshotClient := snapshotefakeclient.NewSimpleClientset()
|
||||
snapshotInformers := snapshotinformers.NewSharedInformerFactory(snapshotClient, 0)
|
||||
|
||||
for _, pvc := range persistentVolumeClaims {
|
||||
_ = informer.Core().V1().PersistentVolumeClaims().Informer().GetIndexer().Add(pvc)
|
||||
}
|
||||
for _, pod := range pods {
|
||||
_ = informer.Core().V1().Pods().Informer().GetIndexer().Add(pod)
|
||||
}
|
||||
for _, volumeSnapshotClass := range volumeSnapshotClasses {
|
||||
_ = snapshotInformers.Snapshot().V1().VolumeSnapshotClasses().Informer().GetIndexer().Add(volumeSnapshotClass)
|
||||
}
|
||||
|
||||
return New(informer, snapshotInformers)
|
||||
}
|
||||
@@ -1,29 +1,21 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package pod
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
@@ -45,34 +37,35 @@ const (
|
||||
)
|
||||
|
||||
type podsGetter struct {
|
||||
informer informers.SharedInformerFactory
|
||||
cache runtimeclient.Reader
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &podsGetter{informer: sharedInformers}
|
||||
func New(cache runtimeclient.Reader) v1alpha3.Interface {
|
||||
return &podsGetter{cache: cache}
|
||||
}
|
||||
|
||||
func (p *podsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return p.informer.Core().V1().Pods().Lister().Pods(namespace).Get(name)
|
||||
pod := &corev1.Pod{}
|
||||
if err := p.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, pod); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.setPodStatus(pod.DeepCopy()), nil
|
||||
}
|
||||
|
||||
func (p *podsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
pods, err := p.informer.Core().V1().Pods().Lister().Pods(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
pods := &corev1.PodList{}
|
||||
if err := p.cache.List(context.Background(), pods, client.InNamespace(namespace),
|
||||
client.MatchingLabelsSelector{Selector: query.Selector()}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, pod := range pods {
|
||||
result = append(result, pod)
|
||||
for _, item := range pods.Items {
|
||||
result = append(result, p.setPodStatus(item.DeepCopy()))
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, p.compare, p.filter), nil
|
||||
}
|
||||
|
||||
func (p *podsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftPod, ok := left.(*corev1.Pod)
|
||||
if !ok {
|
||||
return false
|
||||
@@ -100,8 +93,7 @@ func (p *podsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
case fieldServiceName:
|
||||
return p.podBelongToService(pod, string(filter.Value))
|
||||
case fieldStatus:
|
||||
_, statusType := p.getPodStatus(pod)
|
||||
return statusType == string(filter.Value)
|
||||
return p.getPodStatus(pod) == string(filter.Value)
|
||||
case fieldPhase:
|
||||
return string(pod.Status.Phase) == string(filter.Value)
|
||||
case fieldPodIP:
|
||||
@@ -131,8 +123,8 @@ func (p *podsGetter) podBindPVC(item *corev1.Pod, pvcName string) bool {
|
||||
}
|
||||
|
||||
func (p *podsGetter) podBelongToService(item *corev1.Pod, serviceName string) bool {
|
||||
service, err := p.informer.Core().V1().Services().Lister().Services(item.Namespace).Get(serviceName)
|
||||
if err != nil {
|
||||
service := &corev1.Service{}
|
||||
if err := p.cache.Get(context.Background(), types.NamespacedName{Namespace: item.Namespace, Name: serviceName}, service); err != nil {
|
||||
return false
|
||||
}
|
||||
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
|
||||
@@ -142,13 +134,18 @@ func (p *podsGetter) podBelongToService(item *corev1.Pod, serviceName string) bo
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *podsGetter) setPodStatus(pod *corev1.Pod) *corev1.Pod {
|
||||
pod.Status.Phase = corev1.PodPhase(p.getPodStatus(pod))
|
||||
return pod
|
||||
}
|
||||
|
||||
// getPodStatus refer to `kubectl get po` result.
|
||||
// https://github.com/kubernetes/kubernetes/blob/45279654db87f4908911569c07afc42804f0e246/pkg/printers/internalversion/printers.go#L820-920
|
||||
// podStatusPhase = []string("Pending", "Running","Succeeded","Failed","Unknown")
|
||||
// podStatusReasons = []string{"Evicted", "NodeAffinity", "NodeLost", "Shutdown", "UnexpectedAdmissionError"}
|
||||
// containerWaitingReasons = []string{"ContainerCreating", "CrashLoopBackOff", "CreateContainerConfigError", "ErrImagePull", "ImagePullBackOff", "CreateContainerError", "InvalidImageName"}
|
||||
// containerTerminatedReasons = []string{"OOMKilled", "Completed", "Error", "ContainerCannotRun", "DeadlineExceeded", "Evicted"}
|
||||
func (p *podsGetter) getPodStatus(pod *corev1.Pod) (string, string) {
|
||||
func (p *podsGetter) getPodStatus(pod *corev1.Pod) string {
|
||||
reason := string(pod.Status.Phase)
|
||||
|
||||
if pod.Status.Reason != "" {
|
||||
@@ -251,7 +248,7 @@ func (p *podsGetter) getPodStatus(pod *corev1.Pod) (string, string) {
|
||||
statusType = statusTypeError
|
||||
}
|
||||
}
|
||||
return reason, statusType
|
||||
return statusType
|
||||
}
|
||||
|
||||
func hasPodReadyCondition(conditions []corev1.PodCondition) bool {
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package pod
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
func TestListPods(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldNamespace: query.Value("default")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{foo5, foo4, foo3, foo2, foo1},
|
||||
TotalItems: len(pods),
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"test pvcName filter",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldNamespace: query.Value("default"),
|
||||
fieldPVCName: query.Value(foo4.Spec.Volumes[0].PersistentVolumeClaim.ClaimName),
|
||||
},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{foo4},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"test phase filter",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{
|
||||
query.FieldNamespace: query.Value("default"),
|
||||
fieldPhase: query.Value(corev1.PodRunning),
|
||||
},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{foo5},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
foo2 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
foo3 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo3",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
foo4 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo4",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Volumes: []corev1.Volume{
|
||||
{
|
||||
Name: "data",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: "pvc-1",
|
||||
ReadOnly: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
foo5 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo5",
|
||||
Namespace: "default",
|
||||
},
|
||||
Status: corev1.PodStatus{
|
||||
Phase: corev1.PodRunning,
|
||||
},
|
||||
}
|
||||
|
||||
pods = []interface{}{foo1, foo2, foo3, foo4, foo5}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, pod := range pods {
|
||||
_ = informer.Core().V1().Pods().Informer().GetIndexer().Add(pod)
|
||||
}
|
||||
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,82 +1,46 @@
|
||||
/*
|
||||
Copyright 2020 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.
|
||||
*/
|
||||
* Please refer to the LICENSE file in the root directory of the project.
|
||||
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/volumesnapshotcontent"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/volumesnapshotclass"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/persistentvolume"
|
||||
|
||||
snapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
monitoringdashboardv1alpha2 "kubesphere.io/monitoring-dashboard/api/v1alpha2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
|
||||
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
|
||||
devopsv1alpha3 "kubesphere.io/api/devops/v1alpha3"
|
||||
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
|
||||
networkv1alpha1 "kubesphere.io/api/network/v1alpha1"
|
||||
notificationv2beta2 "kubesphere.io/api/notification/v2beta2"
|
||||
tenantv1alpha1 "kubesphere.io/api/tenant/v1alpha1"
|
||||
tenantv1alpha2 "kubesphere.io/api/tenant/v1alpha2"
|
||||
typesv1beta1 "kubesphere.io/api/types/v1beta1"
|
||||
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
||||
"kubesphere.io/api/tenant/v1beta1"
|
||||
tenantv1beta1 "kubesphere.io/api/tenant/v1beta1"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/application"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/cluster"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/clusterdashboard"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/clusterrole"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/clusterrolebinding"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/configmap"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/cronjob"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/customresourcedefinition"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/daemonset"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/dashboard"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/deployment"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/devops"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedapplication"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedconfigmap"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federateddeployment"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedingress"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatednamespace"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedpersistentvolumeclaim"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedsecret"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedservice"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/federatedstatefulset"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/globalrole"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/globalrolebinding"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/group"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/groupbinding"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/hpa"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/ingress"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/ippool"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/job"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/label"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/loginrecord"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/namespace"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/networkpolicy"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/node"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/notification"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/persistentvolume"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/persistentvolumeclaim"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/pod"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/role"
|
||||
@@ -86,7 +50,6 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/serviceaccount"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/statefulset"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/user"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/volumesnapshot"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspace"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacerole"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacerolebinding"
|
||||
@@ -95,74 +58,53 @@ import (
|
||||
|
||||
var ErrResourceNotSupported = errors.New("resource is not supported")
|
||||
|
||||
type ResourceGetter struct {
|
||||
type Getter struct {
|
||||
clusterResourceGetters map[schema.GroupVersionResource]v1alpha3.Interface
|
||||
namespacedResourceGetters map[schema.GroupVersionResource]v1alpha3.Interface
|
||||
}
|
||||
|
||||
func NewResourceGetter(factory informers.InformerFactory, cache cache.Cache) *ResourceGetter {
|
||||
func NewResourceGetter(cache runtimeclient.Reader, k8sVersion *semver.Version) *Getter {
|
||||
namespacedResourceGetters := make(map[schema.GroupVersionResource]v1alpha3.Interface)
|
||||
clusterResourceGetters := make(map[schema.GroupVersionResource]v1alpha3.Interface)
|
||||
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}] = deployment.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "daemonsets"}] = daemonset.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "statefulsets"}] = statefulset.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "services"}] = service.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"}] = configmap.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"}] = secret.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}] = pod.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "serviceaccounts"}] = serviceaccount.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "ingresses"}] = ingress.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "networkpolicies"}] = networkpolicy.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "jobs"}] = job.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"}] = application.New(cache)
|
||||
clusterResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "persistentvolumes"}] = persistentvolume.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "persistentvolumeclaims"}] = persistentvolumeclaim.New(factory.KubernetesSharedInformerFactory(), factory.SnapshotSharedInformerFactory())
|
||||
namespacedResourceGetters[snapshotv1.SchemeGroupVersion.WithResource("volumesnapshots")] = volumesnapshot.New(factory.SnapshotSharedInformerFactory())
|
||||
clusterResourceGetters[snapshotv1.SchemeGroupVersion.WithResource("volumesnapshotclasses")] = volumesnapshotclass.New(factory.SnapshotSharedInformerFactory())
|
||||
clusterResourceGetters[snapshotv1.SchemeGroupVersion.WithResource("volumesnapshotcontents")] = volumesnapshotcontent.New(factory.SnapshotSharedInformerFactory())
|
||||
namespacedResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralRoleBinding)] = rolebinding.New(factory.KubernetesSharedInformerFactory())
|
||||
namespacedResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralRole)] = role.New(factory.KubernetesSharedInformerFactory())
|
||||
clusterResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "nodes"}] = node.New(factory.KubernetesSharedInformerFactory())
|
||||
clusterResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"}] = namespace.New(factory.KubernetesSharedInformerFactory())
|
||||
clusterResourceGetters[schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"}] = customresourcedefinition.New(factory.ApiExtensionSharedInformerFactory())
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}] = deployment.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "daemonsets"}] = daemonset.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "statefulsets"}] = statefulset.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "services"}] = service.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"}] = configmap.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"}] = secret.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}] = pod.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "serviceaccounts"}] = serviceaccount.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "ingresses"}] = ingress.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "jobs"}] = job.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "cronjobs"}] = cronjob.New(cache, k8sVersion)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "persistentvolumeclaims"}] = persistentvolumeclaim.New(cache)
|
||||
namespacedResourceGetters[schema.GroupVersionResource{Group: "autoscaling", Version: "v2", Resource: "horizontalpodautoscalers"}] = hpa.New(cache, k8sVersion)
|
||||
namespacedResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralRoleBinding)] = rolebinding.New(cache)
|
||||
namespacedResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralRole)] = role.New(cache)
|
||||
|
||||
clusterResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "persistentvolumes"}] = persistentvolume.New(cache)
|
||||
clusterResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "nodes"}] = node.New(cache)
|
||||
clusterResourceGetters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"}] = namespace.New(cache)
|
||||
clusterResourceGetters[schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"}] = customresourcedefinition.New(cache)
|
||||
|
||||
// kubesphere resources
|
||||
namespacedResourceGetters[networkv1alpha1.SchemeGroupVersion.WithResource(networkv1alpha1.ResourcePluralIPPool)] = ippool.New(factory.KubeSphereSharedInformerFactory(), factory.KubernetesSharedInformerFactory())
|
||||
clusterResourceGetters[devopsv1alpha3.SchemeGroupVersion.WithResource(devopsv1alpha3.ResourcePluralDevOpsProject)] = devops.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[tenantv1alpha1.SchemeGroupVersion.WithResource(tenantv1alpha1.ResourcePluralWorkspace)] = workspace.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[tenantv1alpha1.SchemeGroupVersion.WithResource(tenantv1alpha2.ResourcePluralWorkspaceTemplate)] = workspacetemplate.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralGlobalRole)] = globalrole.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralWorkspaceRole)] = workspacerole.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralUser)] = user.New(factory.KubeSphereSharedInformerFactory(), factory.KubernetesSharedInformerFactory())
|
||||
clusterResourceGetters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralGlobalRoleBinding)] = globalrolebinding.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralWorkspaceRoleBinding)] = workspacerolebinding.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralLoginRecord)] = loginrecord.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcePluralGroup)] = group.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcePluralGroupBinding)] = groupbinding.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralClusterRole)] = clusterrole.New(factory.KubernetesSharedInformerFactory())
|
||||
clusterResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralClusterRoleBinding)] = clusterrolebinding.New(factory.KubernetesSharedInformerFactory())
|
||||
clusterResourceGetters[clusterv1alpha1.SchemeGroupVersion.WithResource(clusterv1alpha1.ResourcesPluralCluster)] = cluster.New(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralNotificationManager)] = notification.NewNotificationManagerGetter(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralConfig)] = notification.NewNotificationConfigGetter(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralReceiver)] = notification.NewNotificationReceiverGetter(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralRouter)] = notification.NewNotificationRouterGetter(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralSilence)] = notification.NewNotificationSilenceGetter(factory.KubeSphereSharedInformerFactory())
|
||||
clusterResourceGetters[monitoringdashboardv1alpha2.GroupVersion.WithResource("clusterdashboards")] = clusterdashboard.New(cache)
|
||||
clusterResourceGetters[v1beta1.SchemeGroupVersion.WithResource(v1beta1.ResourcePluralWorkspace)] = workspace.New(cache)
|
||||
clusterResourceGetters[v1beta1.SchemeGroupVersion.WithResource(tenantv1beta1.ResourcePluralWorkspaceTemplate)] = workspacetemplate.New(cache)
|
||||
clusterResourceGetters[iamv1beta1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralGlobalRole)] = globalrole.New(cache)
|
||||
clusterResourceGetters[iamv1beta1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralWorkspaceRole)] = workspacerole.New(cache)
|
||||
clusterResourceGetters[iamv1beta1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralUser)] = user.New(cache)
|
||||
clusterResourceGetters[iamv1beta1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralGlobalRoleBinding)] = globalrolebinding.New(cache)
|
||||
clusterResourceGetters[iamv1beta1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralWorkspaceRoleBinding)] = workspacerolebinding.New(cache)
|
||||
clusterResourceGetters[iamv1beta1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralLoginRecord)] = loginrecord.New(cache)
|
||||
clusterResourceGetters[iamv1beta1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcePluralGroup)] = group.New(cache)
|
||||
clusterResourceGetters[iamv1beta1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcePluralGroupBinding)] = groupbinding.New(cache)
|
||||
clusterResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralClusterRole)] = clusterrole.New(cache)
|
||||
clusterResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1beta1.ResourcesPluralClusterRoleBinding)] = clusterrolebinding.New(cache)
|
||||
clusterResourceGetters[clusterv1alpha1.SchemeGroupVersion.WithResource(clusterv1alpha1.ResourcesPluralCluster)] = cluster.New(cache)
|
||||
clusterResourceGetters[clusterv1alpha1.SchemeGroupVersion.WithResource(clusterv1alpha1.ResourcesPluralLabel)] = label.New(cache)
|
||||
|
||||
// federated resources
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedNamespace)] = federatednamespace.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedDeployment)] = federateddeployment.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedSecret)] = federatedsecret.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedConfigmap)] = federatedconfigmap.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedService)] = federatedservice.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedApplication)] = federatedapplication.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedPersistentVolumeClaim)] = federatedpersistentvolumeclaim.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedStatefulSet)] = federatedstatefulset.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedIngress)] = federatedingress.New(factory.KubeSphereSharedInformerFactory())
|
||||
namespacedResourceGetters[monitoringdashboardv1alpha2.GroupVersion.WithResource("dashboards")] = dashboard.New(cache)
|
||||
|
||||
return &ResourceGetter{
|
||||
return &Getter{
|
||||
namespacedResourceGetters: namespacedResourceGetters,
|
||||
clusterResourceGetters: clusterResourceGetters,
|
||||
}
|
||||
@@ -170,7 +112,7 @@ func NewResourceGetter(factory informers.InformerFactory, cache cache.Cache) *Re
|
||||
|
||||
// TryResource will retrieve a getter with resource name, it doesn't guarantee find resource with correct group version
|
||||
// need to refactor this use schema.GroupVersionResource
|
||||
func (r *ResourceGetter) TryResource(clusterScope bool, resource string) v1alpha3.Interface {
|
||||
func (r *Getter) TryResource(clusterScope bool, resource string) v1alpha3.Interface {
|
||||
if clusterScope {
|
||||
for k, v := range r.clusterResourceGetters {
|
||||
if k.Resource == resource {
|
||||
@@ -186,7 +128,7 @@ func (r *ResourceGetter) TryResource(clusterScope bool, resource string) v1alpha
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ResourceGetter) Get(resource, namespace, name string) (runtime.Object, error) {
|
||||
func (r *Getter) Get(resource, namespace, name string) (runtime.Object, error) {
|
||||
clusterScope := namespace == ""
|
||||
getter := r.TryResource(clusterScope, resource)
|
||||
if getter == nil {
|
||||
@@ -195,7 +137,7 @@ func (r *ResourceGetter) Get(resource, namespace, name string) (runtime.Object,
|
||||
return getter.Get(namespace, name)
|
||||
}
|
||||
|
||||
func (r *ResourceGetter) List(resource, namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
func (r *Getter) List(resource, namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
clusterScope := namespace == ""
|
||||
getter := r.TryResource(clusterScope, resource)
|
||||
if getter == nil {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user