237 lines
6.5 KiB
Go
237 lines
6.5 KiB
Go
// Copyright (C) INFINI Labs & INFINI LIMITED.
|
|
//
|
|
// The INFINI Console is offered under the GNU Affero General Public License v3.0
|
|
// and as commercial software.
|
|
//
|
|
// For commercial licensing, contact us at:
|
|
// - Website: infinilabs.com
|
|
// - Email: hello@infini.ltd
|
|
//
|
|
// Open Source licensed under AGPL V3:
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
/* Copyright © INFINI Ltd. All rights reserved.
|
|
* Web: https://infinilabs.com
|
|
* Email: hello#infini.ltd */
|
|
|
|
package platform
|
|
|
|
import (
|
|
"infini.sh/console/core/security/enum"
|
|
consoleModel "infini.sh/console/model"
|
|
"infini.sh/console/model/alerting"
|
|
"infini.sh/console/model/insight"
|
|
"infini.sh/framework/core/elastic"
|
|
"infini.sh/framework/core/event"
|
|
"infini.sh/framework/core/model"
|
|
"infini.sh/framework/core/util"
|
|
"net/http"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
var (
|
|
collectionMetas map[string]CollectionMeta
|
|
metasInitOnce sync.Once
|
|
)
|
|
|
|
func GetCollectionMetas() map[string]CollectionMeta {
|
|
metasInitOnce.Do(func() {
|
|
collectionMetas = map[string]CollectionMeta{
|
|
"gateway": {
|
|
Name: "gateway",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionGatewayInstanceRead,
|
|
},
|
|
},
|
|
MatchObject: &model.Instance{},
|
|
},
|
|
"agent": {
|
|
Name: "agent",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionAgentInstanceRead,
|
|
},
|
|
},
|
|
MatchObject: &model.Instance{},
|
|
},
|
|
"cluster": {
|
|
Name: "cluster",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionElasticsearchClusterRead,
|
|
},
|
|
},
|
|
MatchObject: &elastic.ElasticsearchConfig{},
|
|
GetSearchRequestBodyFilter: func(api *PlatformAPI, req *http.Request) (util.MapStr, bool) {
|
|
return api.GetClusterFilter(req, "id")
|
|
},
|
|
},
|
|
"node": {
|
|
Name: "node",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionElasticsearchNodeRead,
|
|
},
|
|
},
|
|
MatchObject: &elastic.NodeConfig{},
|
|
},
|
|
"index": {
|
|
Name: "index",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionElasticsearchIndexRead,
|
|
},
|
|
},
|
|
MatchObject: &elastic.IndexConfig{},
|
|
},
|
|
"command": {
|
|
Name: "command",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionCommandRead,
|
|
},
|
|
},
|
|
MatchObject: &elastic.CommonCommand{},
|
|
},
|
|
"activity": {
|
|
Name: "activity",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionActivityRead,
|
|
},
|
|
},
|
|
MatchObject: &event.Activity{},
|
|
GetSearchRequestBodyFilter: func(api *PlatformAPI, req *http.Request) (util.MapStr, bool) {
|
|
clusterFilter, hasAllPrivilege := api.GetClusterFilter(req, "metadata.labels.cluster_id")
|
|
if !hasAllPrivilege && clusterFilter == nil {
|
|
return clusterFilter, hasAllPrivilege
|
|
}
|
|
var filter []util.MapStr
|
|
if !hasAllPrivilege && clusterFilter != nil {
|
|
filter = append(filter, clusterFilter)
|
|
}
|
|
|
|
hasAllPrivilege, indexPrivilege := api.GetCurrentUserIndex(req)
|
|
if !hasAllPrivilege && len(indexPrivilege) == 0 {
|
|
return nil, hasAllPrivilege
|
|
}
|
|
if !hasAllPrivilege {
|
|
indexShould := make([]interface{}, 0, len(indexPrivilege))
|
|
for clusterID, indices := range indexPrivilege {
|
|
var (
|
|
wildcardIndices []string
|
|
normalIndices []string
|
|
)
|
|
for _, index := range indices {
|
|
if strings.Contains(index, "*") {
|
|
wildcardIndices = append(wildcardIndices, index)
|
|
continue
|
|
}
|
|
normalIndices = append(normalIndices, index)
|
|
}
|
|
subShould := []util.MapStr{}
|
|
if len(wildcardIndices) > 0 {
|
|
subShould = append(subShould, util.MapStr{
|
|
"query_string": util.MapStr{
|
|
"query": strings.Join(wildcardIndices, " "),
|
|
"fields": []string{"metadata.labels.index_name"},
|
|
"default_operator": "OR",
|
|
},
|
|
})
|
|
}
|
|
if len(normalIndices) > 0 {
|
|
subShould = append(subShould, util.MapStr{
|
|
"terms": util.MapStr{
|
|
"metadata.labels.index_name": normalIndices,
|
|
},
|
|
})
|
|
}
|
|
indexShould = append(indexShould, util.MapStr{
|
|
"bool": util.MapStr{
|
|
"must": []util.MapStr{
|
|
{
|
|
"wildcard": util.MapStr{
|
|
"metadata.labels.cluster_id": util.MapStr{
|
|
"value": clusterID,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"bool": util.MapStr{
|
|
"minimum_should_match": 1,
|
|
"should": subShould,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
indexFilter := util.MapStr{
|
|
"bool": util.MapStr{
|
|
"minimum_should_match": 1,
|
|
"should": indexShould,
|
|
},
|
|
}
|
|
filter = append(filter, indexFilter)
|
|
}
|
|
return util.MapStr{
|
|
"bool": util.MapStr{
|
|
"must": filter,
|
|
},
|
|
}, hasAllPrivilege
|
|
},
|
|
},
|
|
"audit_log": {
|
|
Name: "audit_log",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionAuditLogRead,
|
|
},
|
|
},
|
|
MatchObject: &consoleModel.AuditLog{},
|
|
},
|
|
"alerting_rule": {
|
|
Name: "alerting_rule",
|
|
RequirePermission: map[string][]string{
|
|
"read": {
|
|
enum.PermissionAlertRuleRead,
|
|
},
|
|
},
|
|
MatchObject: &alerting.Rule{},
|
|
},
|
|
"metric": {
|
|
Name: "metric",
|
|
MatchObject: &insight.MetricBase{},
|
|
},
|
|
}
|
|
})
|
|
return collectionMetas
|
|
}
|
|
|
|
// CollectionMeta includes information about how to visit backend index
|
|
type CollectionMeta struct {
|
|
//collection name
|
|
Name string `json:"name"`
|
|
//permissions required to visit collection
|
|
RequirePermission map[string][]string `json:"require_permission"`
|
|
//use for orm.GetIndexName to get real index name
|
|
MatchObject interface{} `json:"match_object"`
|
|
//configure GetSearchRequestBodyFilter to filter search request dsl
|
|
GetSearchRequestBodyFilter SearchRequestBodyFilter
|
|
}
|
|
|
|
type SearchRequestBodyFilter func(api *PlatformAPI, req *http.Request) (util.MapStr, bool)
|