add response_code_filter parameter in auditing events search api
This commit is contained in:
@@ -45,7 +45,8 @@ type Query struct {
|
|||||||
SourceIpSearch string `json:"source_ip_search,omitempty"`
|
SourceIpSearch string `json:"source_ip_search,omitempty"`
|
||||||
ObjectRefResourceFilter string `json:"objectref_resource_filter,omitempty"`
|
ObjectRefResourceFilter string `json:"objectref_resource_filter,omitempty"`
|
||||||
ObjectRefSubresourceFilter string `json:"objectref_subresource_filter,omitempty"`
|
ObjectRefSubresourceFilter string `json:"objectref_subresource_filter,omitempty"`
|
||||||
ResponesStatusFilter string `json:"response_status_filter,omitempty"`
|
ResponseCodeFilter string `json:"response_code_filter,omitempty"`
|
||||||
|
ResponseStatusFilter string `json:"response_status_filter,omitempty"`
|
||||||
|
|
||||||
StartTime *time.Time `json:"start_time,omitempty"`
|
StartTime *time.Time `json:"start_time,omitempty"`
|
||||||
EndTime *time.Time `json:"end_time,omitempty"`
|
EndTime *time.Time `json:"end_time,omitempty"`
|
||||||
@@ -74,7 +75,8 @@ func ParseQueryParameter(req *restful.Request) (*Query, error) {
|
|||||||
q.GroupSearch = req.QueryParameter("group_search")
|
q.GroupSearch = req.QueryParameter("group_search")
|
||||||
q.ObjectRefResourceFilter = req.QueryParameter("objectref_resource_filter")
|
q.ObjectRefResourceFilter = req.QueryParameter("objectref_resource_filter")
|
||||||
q.ObjectRefSubresourceFilter = req.QueryParameter("objectref_subresource_filter")
|
q.ObjectRefSubresourceFilter = req.QueryParameter("objectref_subresource_filter")
|
||||||
q.ResponesStatusFilter = req.QueryParameter("response_status_filter")
|
q.ResponseCodeFilter = req.QueryParameter("response_code_filter")
|
||||||
|
q.ResponseStatusFilter = req.QueryParameter("response_status_filter")
|
||||||
|
|
||||||
if tstr := req.QueryParameter("start_time"); tstr != "" {
|
if tstr := req.QueryParameter("start_time"); tstr != "" {
|
||||||
sec, err := strconv.ParseInt(tstr, 10, 64)
|
sec, err := strconv.ParseInt(tstr, 10, 64)
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8s
|
|||||||
Param(ws.QueryParameter("source_ip_search", "A comma-separated list of keywords. This field performs fuzzy matching on 'SourceIPs'. For example, the following value limits the query to SourceIPs which contains 127.0 *OR* 192.168.: `127.0,192.168.`.")).
|
Param(ws.QueryParameter("source_ip_search", "A comma-separated list of keywords. This field performs fuzzy matching on 'SourceIPs'. For example, the following value limits the query to SourceIPs which contains 127.0 *OR* 192.168.: `127.0,192.168.`.")).
|
||||||
Param(ws.QueryParameter("objectref_resource_filter", "A comma-separated list of resource. This field restricts the query to specified ip. This field restricts the query to specified `ObjectRef.Resource`.")).
|
Param(ws.QueryParameter("objectref_resource_filter", "A comma-separated list of resource. This field restricts the query to specified ip. This field restricts the query to specified `ObjectRef.Resource`.")).
|
||||||
Param(ws.QueryParameter("objectref_subresource_filter", "A comma-separated list of subresource. This field restricts the query to specified subresource. This field restricts the query to specified `ObjectRef.Subresource`.")).
|
Param(ws.QueryParameter("objectref_subresource_filter", "A comma-separated list of subresource. This field restricts the query to specified subresource. This field restricts the query to specified `ObjectRef.Subresource`.")).
|
||||||
Param(ws.QueryParameter("response_status_filter", "A comma-separated list of response status code. This field restricts the query to specified response status code. This field restricts the query to specified `ResponseStatus.Code`.")).
|
Param(ws.QueryParameter("response_code_filter", "A comma-separated list of response status code. This field restricts the query to specified response status code. This field restricts the query to specified `ResponseStatus.code`.")).
|
||||||
|
Param(ws.QueryParameter("response_status_filter", "A comma-separated list of response status. This field restricts the query to specified response status. This field restricts the query to specified `ResponseStatus.status`.")).
|
||||||
Param(ws.QueryParameter("start_time", "Start time of query (limits `RequestReceivedTimestamp`). The format is a string representing seconds since the epoch, eg. 1136214245.")).
|
Param(ws.QueryParameter("start_time", "Start time of query (limits `RequestReceivedTimestamp`). The format is a string representing seconds since the epoch, eg. 1136214245.")).
|
||||||
Param(ws.QueryParameter("end_time", "End time of query (limits `RequestReceivedTimestamp`). The format is a string representing seconds since the epoch, eg. 1136214245.")).
|
Param(ws.QueryParameter("end_time", "End time of query (limits `RequestReceivedTimestamp`). The format is a string representing seconds since the epoch, eg. 1136214245.")).
|
||||||
Param(ws.QueryParameter("interval", "Time interval. It requires **operation** is set to `histogram`. The format is [0-9]+[smhdwMqy]. Defaults to 15m (i.e. 15 min).").DefaultValue("15m")).
|
Param(ws.QueryParameter("interval", "Time interval. It requires **operation** is set to `histogram`. The format is [0-9]+[smhdwMqy]. Defaults to 15m (i.e. 15 min).").DefaultValue("15m")).
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ func (eo *eventsOperator) Events(queryParam *v1alpha1.Query,
|
|||||||
SourceIpFuzzy: stringutils.Split(queryParam.SourceIpSearch, ","),
|
SourceIpFuzzy: stringutils.Split(queryParam.SourceIpSearch, ","),
|
||||||
ObjectRefResources: stringutils.Split(queryParam.ObjectRefResourceFilter, ","),
|
ObjectRefResources: stringutils.Split(queryParam.ObjectRefResourceFilter, ","),
|
||||||
ObjectRefSubresources: stringutils.Split(queryParam.ObjectRefSubresourceFilter, ","),
|
ObjectRefSubresources: stringutils.Split(queryParam.ObjectRefSubresourceFilter, ","),
|
||||||
|
ResponseStatus: stringutils.Split(queryParam.ResponseStatusFilter, ","),
|
||||||
StartTime: queryParam.StartTime,
|
StartTime: queryParam.StartTime,
|
||||||
EndTime: queryParam.EndTime,
|
EndTime: queryParam.EndTime,
|
||||||
}
|
}
|
||||||
@@ -55,14 +56,14 @@ func (eo *eventsOperator) Events(queryParam *v1alpha1.Query,
|
|||||||
MutateFilterFunc(filter)
|
MutateFilterFunc(filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := stringutils.Split(queryParam.ResponesStatusFilter, ",")
|
cs := stringutils.Split(queryParam.ResponseCodeFilter, ",")
|
||||||
for _, c := range cs {
|
for _, c := range cs {
|
||||||
code, err := strconv.ParseInt(c, 10, 64)
|
code, err := strconv.ParseInt(c, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
filter.ResponseStatus = append(filter.ResponseStatus, int32(code))
|
filter.ResponseCodes = append(filter.ResponseCodes, int32(code))
|
||||||
}
|
}
|
||||||
|
|
||||||
var ar v1alpha1.APIResponse
|
var ar v1alpha1.APIResponse
|
||||||
|
|||||||
@@ -361,10 +361,10 @@ func parseToQueryPart(f *auditing.Filter) interface{} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.ResponseStatus != nil && len(f.ResponseStatus) > 0 {
|
if f.ResponseCodes != nil && len(f.ResponseCodes) > 0 {
|
||||||
|
|
||||||
bi := BoolBody{MinimumShouldMatch: &mini}
|
bi := BoolBody{MinimumShouldMatch: &mini}
|
||||||
for _, v := range f.ResponseStatus {
|
for _, v := range f.ResponseCodes {
|
||||||
bi.Should = append(bi.Should, map[string]interface{}{
|
bi.Should = append(bi.Should, map[string]interface{}{
|
||||||
"term": map[string]int32{"ResponseStatus.code": v},
|
"term": map[string]int32{"ResponseStatus.code": v},
|
||||||
})
|
})
|
||||||
@@ -373,6 +373,13 @@ func parseToQueryPart(f *auditing.Filter) interface{} {
|
|||||||
b.Filter = append(b.Filter, map[string]interface{}{"bool": bi})
|
b.Filter = append(b.Filter, map[string]interface{}{"bool": bi})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(f.ResponseStatus) > 0 {
|
||||||
|
if bi := shouldBoolbody("match_phrase", "ResponseStatus.status",
|
||||||
|
f.ResponseStatus, nil); bi != nil {
|
||||||
|
b.Filter = append(b.Filter, map[string]interface{}{"bool": bi})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if f.StartTime != nil || f.EndTime != nil {
|
if f.StartTime != nil || f.EndTime != nil {
|
||||||
m := make(map[string]*time.Time)
|
m := make(map[string]*time.Time)
|
||||||
if f.StartTime != nil {
|
if f.StartTime != nil {
|
||||||
|
|||||||
@@ -171,6 +171,18 @@ func TestParseToQueryPart(t *testing.T) {
|
|||||||
"minimum_should_match": 1
|
"minimum_should_match": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"match_phrase_prefix": {
|
||||||
|
"ObjectRef.Name.keyword": "istio"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"bool": {
|
"bool": {
|
||||||
"should": [
|
"should": [
|
||||||
@@ -183,10 +195,131 @@ func TestParseToQueryPart(t *testing.T) {
|
|||||||
"minimum_should_match": 1
|
"minimum_should_match": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"match_phrase": {
|
||||||
|
"Verb": "create"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"match_phrase": {
|
||||||
|
"Level": "Metadata"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"wildcard": {
|
||||||
|
"SourceIPs": "*192.168*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"match_phrase": {
|
||||||
|
"User.Username.keyword": "system:serviceaccount:kubesphere-system:kubesphere"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"wildcard": {
|
||||||
|
"User.Username": "*system:serviceaccount*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"wildcard": {
|
||||||
|
"User.Groups": "*system:serviceaccounts*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"match_phrase_prefix": {
|
||||||
|
"ObjectRef.Resource.keyword": "devops"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"match_phrase_prefix": {
|
||||||
|
"ObjectRef.Subresource.keyword": "pipeline"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"term": {
|
||||||
|
"ResponseStatus.code": 404
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"match_phrase": {
|
||||||
|
"ResponseStatus.status": "Failure"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum_should_match": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
"RequestReceivedTimestamp": {
|
"RequestReceivedTimestamp": {
|
||||||
"gte": "2019-12-01T01:01:01.000000001Z"
|
"gte": "2019-12-01T01:01:01.000000001Z",
|
||||||
|
"lte": "2020-01-01T01:01:01.000000001Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,13 +329,26 @@ func TestParseToQueryPart(t *testing.T) {
|
|||||||
`
|
`
|
||||||
nsCreateTime := time.Date(2020, time.Month(1), 1, 1, 1, 1, 1, time.UTC)
|
nsCreateTime := time.Date(2020, time.Month(1), 1, 1, 1, 1, 1, time.UTC)
|
||||||
startTime := nsCreateTime.AddDate(0, -1, 0)
|
startTime := nsCreateTime.AddDate(0, -1, 0)
|
||||||
|
endTime := nsCreateTime.AddDate(0, 0, 0)
|
||||||
|
|
||||||
filter := &auditing.Filter{
|
filter := &auditing.Filter{
|
||||||
ObjectRefNamespaceMap: map[string]time.Time{
|
ObjectRefNamespaceMap: map[string]time.Time{
|
||||||
"kubesphere-system": nsCreateTime,
|
"kubesphere-system": nsCreateTime,
|
||||||
},
|
},
|
||||||
|
ObjectRefNames: []string{"istio"},
|
||||||
ObjectRefNameFuzzy: []string{"istio"},
|
ObjectRefNameFuzzy: []string{"istio"},
|
||||||
|
Levels: []string{"Metadata"},
|
||||||
|
Verbs: []string{"create"},
|
||||||
|
Users: []string{"system:serviceaccount:kubesphere-system:kubesphere"},
|
||||||
|
UserFuzzy: []string{"system:serviceaccount"},
|
||||||
|
GroupFuzzy: []string{"system:serviceaccounts"},
|
||||||
|
SourceIpFuzzy: []string{"192.168"},
|
||||||
|
ObjectRefResources: []string{"devops"},
|
||||||
|
ObjectRefSubresources: []string{"pipeline"},
|
||||||
|
ResponseCodes: []int32{404},
|
||||||
|
ResponseStatus: []string{"Failure"},
|
||||||
StartTime: &startTime,
|
StartTime: &startTime,
|
||||||
|
EndTime: &endTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
qp := parseToQueryPart(filter)
|
qp := parseToQueryPart(filter)
|
||||||
|
|||||||
@@ -47,15 +47,15 @@ func (s *Options) Validate() []error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Options) AddFlags(fs *pflag.FlagSet, c *Options) {
|
func (s *Options) AddFlags(fs *pflag.FlagSet, c *Options) {
|
||||||
fs.StringVar(&s.Host, "elasticsearch-host", c.Host, ""+
|
fs.StringVar(&s.Host, "auditing-elasticsearch-host", c.Host, ""+
|
||||||
"Elasticsearch service host. KubeSphere is using elastic as auditing store, "+
|
"Elasticsearch service host. KubeSphere is using elastic as auditing store, "+
|
||||||
"if this filed left blank, KubeSphere will use kubernetes builtin event API instead, and"+
|
"if this filed left blank, KubeSphere will use kubernetes builtin event API instead, and"+
|
||||||
" the following elastic search options will be ignored.")
|
" the following elastic search options will be ignored.")
|
||||||
|
|
||||||
fs.StringVar(&s.IndexPrefix, "index-prefix", c.IndexPrefix, ""+
|
fs.StringVar(&s.IndexPrefix, "auditing-index-prefix", c.IndexPrefix, ""+
|
||||||
"Index name prefix. KubeSphere will retrieve auditing against indices matching the prefix.")
|
"Index name prefix. KubeSphere will retrieve auditing against indices matching the prefix.")
|
||||||
|
|
||||||
fs.StringVar(&s.Version, "elasticsearch-version", c.Version, ""+
|
fs.StringVar(&s.Version, "auditing-elasticsearch-version", c.Version, ""+
|
||||||
"Elasticsearch major version, e.g. 5/6/7, if left blank, will detect automatically."+
|
"Elasticsearch major version, e.g. 5/6/7, if left blank, will detect automatically."+
|
||||||
"Currently, minimum supported version is 5.x")
|
"Currently, minimum supported version is 5.x")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ type Filter struct {
|
|||||||
SourceIpFuzzy []string
|
SourceIpFuzzy []string
|
||||||
ObjectRefResources []string
|
ObjectRefResources []string
|
||||||
ObjectRefSubresources []string
|
ObjectRefSubresources []string
|
||||||
ResponseStatus []int32
|
ResponseCodes []int32
|
||||||
|
ResponseStatus []string
|
||||||
StartTime *time.Time
|
StartTime *time.Time
|
||||||
EndTime *time.Time
|
EndTime *time.Time
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user