support fieldselector filter query secrets (#5300)
* support fieldselector filter query secrets Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com> * support fieldselector filter query secrets Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com> * support fieldselector filter query secrets Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com> * support fieldselector filter query secrets Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com> * support fieldselector filter query secrets Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com> Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
This commit is contained in:
@@ -88,6 +88,7 @@ func AddToContainer(c *restful.Container, informerFactory informers.InformerFact
|
||||
Param(webservice.QueryParameter(query.ParameterLimit, "limit").Required(false)).
|
||||
Param(webservice.QueryParameter(query.ParameterAscending, "sort parameters, e.g. reverse=true").Required(false).DefaultValue("ascending=false")).
|
||||
Param(webservice.QueryParameter(query.ParameterOrderBy, "sort parameters, e.g. orderBy=createTime")).
|
||||
Param(webservice.QueryParameter(query.ParameterFieldSelector, "field selector used for filtering, you can use the = , == and != operators with field selectors( = and == mean the same thing), e.g. fieldSelector=type=kubernetes.io/dockerconfigjson, multiple separated by comma").Required(false)).
|
||||
Returns(http.StatusOK, ok, api.ListResult{}))
|
||||
|
||||
webservice.Route(webservice.GET("/namespaces/{namespace}/{resources}/{name}").
|
||||
|
||||
@@ -17,13 +17,20 @@ limitations under the License.
|
||||
package secret
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/klog"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
|
||||
"github.com/oliveagle/jsonpath"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
@@ -74,5 +81,55 @@ func (s *secretSearcher) filter(object runtime.Object, filter query.Filter) bool
|
||||
return false
|
||||
}
|
||||
|
||||
if filter.Field == query.ParameterFieldSelector {
|
||||
return contains(secret, filter.Value)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(secret.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
// implement a generic query filter to support multiple field selectors with "jsonpath.JsonPathLookup"
|
||||
// https://github.com/oliveagle/jsonpath/blob/master/readme.md
|
||||
func contains(secret *v1.Secret, queryValue query.Value) bool {
|
||||
// call the ParseSelector function of "k8s.io/apimachinery/pkg/fields/selector.go" to validate and parse the selector
|
||||
fieldSelector, err := fields.ParseSelector(string(queryValue))
|
||||
if err != nil {
|
||||
klog.V(4).Infof("failed parse selector error: %s", err)
|
||||
return false
|
||||
}
|
||||
for _, requirement := range fieldSelector.Requirements() {
|
||||
var negative bool
|
||||
// supports '=', '==' and '!='.(e.g. ?fieldSelector=key1=value1,key2=value2)
|
||||
switch requirement.Operator {
|
||||
case selection.NotEquals:
|
||||
negative = true
|
||||
case selection.DoubleEquals:
|
||||
case selection.Equals:
|
||||
negative = false
|
||||
}
|
||||
key := requirement.Field
|
||||
value := requirement.Value
|
||||
|
||||
var input map[string]interface{}
|
||||
data, err := json.Marshal(secret)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("failed marshal to JSON string: %s", err)
|
||||
return false
|
||||
}
|
||||
if err = json.Unmarshal(data, &input); err != nil {
|
||||
klog.V(4).Infof("failed unmarshal to map object: %s", err)
|
||||
return false
|
||||
}
|
||||
rawValue, err := jsonpath.JsonPathLookup(input, "$."+key)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("failed to lookup jsonpath: %s", err)
|
||||
return false
|
||||
}
|
||||
if (negative && fmt.Sprintf("%v", rawValue) != value) || (!negative && fmt.Sprintf("%v", rawValue) == value) {
|
||||
continue
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user