mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
support joint filter
This commit is contained in:
Generated
+10
-5
@@ -666,13 +666,15 @@
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d867dfa6751c8d7a435821ad3b736310c2ed68945d05b50fb9d23aee0540c8cc"
|
||||
branch = "master"
|
||||
digest = "1:c1f242537d2898c84fe9bfd8bd94b177cd5ff98a10c397dbbc494f4e2b173be6"
|
||||
name = "github.com/serialx/hashring"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "49a4782e9908fe098c907022a1bd7519c79803d6"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d867dfa6751c8d7a435821ad3b736310c2ed68945d05b50fb9d23aee0540c8cc"
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
@@ -1040,18 +1042,18 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:b707a5d591b21dad9ebdb264281632ed43d34e2b980dce967acb2c7adcc93ad3"
|
||||
digest = "1:636db180d3fc734536a5437d93bb6fe937feb036c1ed062c25872a47c4283163"
|
||||
name = "yunion.io/x/log"
|
||||
packages = [
|
||||
".",
|
||||
"hooks",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a10b94c5038480920262e0f344656328434955a2"
|
||||
revision = "5185c49f6d361f61e561fbccba1bedcc7c62748b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:47670c70d0326f624de21c8f29d0f73850062f0752f27e146308db62fbb540d3"
|
||||
digest = "1:8e2a4d71738e5e3bffc415b23f100b0a5033dbf88154783122f5147d4fc213b5"
|
||||
name = "yunion.io/x/pkg"
|
||||
packages = [
|
||||
"gotypes",
|
||||
@@ -1086,7 +1088,7 @@
|
||||
"utils",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "6c349ecbdb90d5f6ecc9b86596428176c1937b32"
|
||||
revision = "7348c84865abac3fcdec618591b7eee7c2e0669b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -1109,6 +1111,7 @@
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk",
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors",
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests",
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss",
|
||||
"github.com/aokoli/goutils",
|
||||
@@ -1147,6 +1150,7 @@
|
||||
"github.com/mholt/caddy/startupshutdown",
|
||||
"github.com/miekg/dns",
|
||||
"github.com/moul/http2curl",
|
||||
"github.com/serialx/hashring",
|
||||
"github.com/stretchr/testify/assert",
|
||||
"github.com/vmware/govmomi",
|
||||
"github.com/vmware/govmomi/object",
|
||||
@@ -1158,6 +1162,7 @@
|
||||
"golang.org/x/crypto/ssh",
|
||||
"gopkg.in/gin-gonic/gin.v1",
|
||||
"k8s.io/api/core/v1",
|
||||
"k8s.io/apimachinery/pkg/api/errors",
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"k8s.io/apimachinery/pkg/fields",
|
||||
"k8s.io/apimachinery/pkg/labels",
|
||||
|
||||
@@ -251,6 +251,30 @@ func applyListItemsGeneralFilters(manager IModelManager, q *sqlchemy.SQuery,
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func applyListItemsGeneralJointFilters(manager IModelManager, q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential, jointFilters []string, filterAny bool) (*sqlchemy.SQuery, error) {
|
||||
for _, f := range jointFilters {
|
||||
jfc := filterclause.ParseJointFilterClause(f)
|
||||
if jfc != nil {
|
||||
jointModelManager := GetModelManager(jfc.GetJointModelName())
|
||||
schFields := searchFields(jointModelManager, userCred)
|
||||
if ok, _ := utils.InStringArray(jfc.GetField(), schFields); ok {
|
||||
sq := jointModelManager.Query(jfc.ReleatedKey)
|
||||
cond := jfc.GetJointFilter(sq)
|
||||
if cond != nil {
|
||||
sq = sq.Filter(cond)
|
||||
if filterAny {
|
||||
q = q.Filter(sqlchemy.OR(sqlchemy.In(q.Field("id"), sq)))
|
||||
} else {
|
||||
q = q.Filter(sqlchemy.AND(sqlchemy.In(q.Field("id"), sq)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func listItemQueryFilters(manager IModelManager, ctx context.Context, q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
|
||||
@@ -272,11 +296,15 @@ func listItemQueryFilters(manager IModelManager, ctx context.Context, q *sqlchem
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
filterAny, _ := query.Bool("filter_any")
|
||||
filters := jsonutils.GetQueryStringArray(query, "filter")
|
||||
if len(filters) > 0 {
|
||||
filterAny, _ := query.Bool("filter_any")
|
||||
q, err = applyListItemsGeneralFilters(manager, q, userCred, filters, filterAny)
|
||||
}
|
||||
jointFilter := jsonutils.GetQueryStringArray(query, "joint_filter")
|
||||
if len(jointFilter) > 0 {
|
||||
q, _ = applyListItemsGeneralJointFilters(manager, q, userCred, jointFilter, filterAny)
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
package hooks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type LogFileHook struct {
|
||||
FileDir string
|
||||
FileName string
|
||||
fullPath string
|
||||
file *os.File
|
||||
written int64
|
||||
}
|
||||
|
||||
func (h *LogFileHook) Init() error {
|
||||
if fi, err := os.Lstat(h.FileDir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
os.MkdirAll(h.FileDir, 0755)
|
||||
} else {
|
||||
return fmt.Errorf("Lstat %s: %s", h.FileDir, err)
|
||||
}
|
||||
} else if !fi.Mode().IsDir() {
|
||||
return fmt.Errorf("%s exists and it's not a directory", h.FileDir)
|
||||
}
|
||||
|
||||
h.fullPath = filepath.Join(h.FileDir, h.FileName)
|
||||
file, err := os.OpenFile(h.fullPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
|
||||
if err != nil {
|
||||
return fmt.Errorf("OpenFile %s: %s", h.fullPath, err)
|
||||
}
|
||||
h.file = file
|
||||
h.written = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *LogFileHook) DeInit() {
|
||||
if h.file != nil {
|
||||
h.file.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (h *LogFileHook) Levels() []logrus.Level {
|
||||
return logrus.AllLevels
|
||||
}
|
||||
|
||||
func (h *LogFileHook) Fire(e *logrus.Entry) error {
|
||||
if b, err := e.Logger.Formatter.Format(e); err != nil {
|
||||
return err
|
||||
} else {
|
||||
n, err := h.file.Write(b)
|
||||
h.written += int64(n)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *LogFileHook) Written() int64 {
|
||||
return h.written
|
||||
}
|
||||
|
||||
// rotate by size
|
||||
type LogFileRotateHook struct {
|
||||
LogFileHook
|
||||
RotateNum int
|
||||
RotateSize int64
|
||||
filePaths []string
|
||||
}
|
||||
|
||||
func (h *LogFileRotateHook) Init() error {
|
||||
if err := h.LogFileHook.Init(); err != nil {
|
||||
return err
|
||||
}
|
||||
h.filePaths = make([]string, h.RotateNum)
|
||||
for i := 1; i < h.RotateNum; i++ {
|
||||
fileName := fmt.Sprintf("%s.%d", h.FileName, i)
|
||||
filePath := filepath.Join(h.FileDir, fileName)
|
||||
h.filePaths[i] = filePath
|
||||
}
|
||||
h.filePaths[0] = filepath.Join(h.FileDir, h.FileName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *LogFileRotateHook) rotate() {
|
||||
for i := h.RotateNum - 1; i > 0; i-- {
|
||||
filePath0 := h.filePaths[i-1]
|
||||
if _, err := os.Lstat(filePath0); err != nil {
|
||||
continue
|
||||
}
|
||||
filePath1 := h.filePaths[i]
|
||||
os.Rename(filePath0, filePath1)
|
||||
}
|
||||
h.LogFileHook.DeInit()
|
||||
h.LogFileHook.Init()
|
||||
}
|
||||
|
||||
func (h *LogFileRotateHook) Fire(e *logrus.Entry) error {
|
||||
if err := h.LogFileHook.Fire(e); err != nil {
|
||||
return err
|
||||
}
|
||||
if h.LogFileHook.Written() >= h.RotateSize {
|
||||
h.rotate()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+1
-6
@@ -12,14 +12,9 @@ type StdioHook struct{}
|
||||
func (hook *StdioHook) Fire(entry *logrus.Entry) error {
|
||||
line, err := entry.String()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||
return err
|
||||
}
|
||||
if entry.Level >= logrus.ErrorLevel {
|
||||
fmt.Fprintf(os.Stderr, line)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stdout, line)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, line)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+35
-1
@@ -16,6 +16,20 @@ type SFilterClause struct {
|
||||
params []string
|
||||
}
|
||||
|
||||
type SJointFilterClause struct {
|
||||
SFilterClause
|
||||
JointModel string
|
||||
ReleatedKey string
|
||||
}
|
||||
|
||||
func (jfc *SJointFilterClause) GetJointFilter(q *sqlchemy.SQuery) sqlchemy.ICondition {
|
||||
return jfc.QueryCondition(q)
|
||||
}
|
||||
|
||||
func (jfc *SJointFilterClause) GetJointModelName() string {
|
||||
return jfc.JointModel[:len(jfc.JointModel)-1]
|
||||
}
|
||||
|
||||
func (fc *SFilterClause) QueryCondition(q *sqlchemy.SQuery) sqlchemy.ICondition {
|
||||
field := q.Field(fc.field)
|
||||
if field == nil {
|
||||
@@ -63,11 +77,13 @@ func (fc *SFilterClause) String() string {
|
||||
}
|
||||
|
||||
var (
|
||||
filterClausePattern *regexp.Regexp
|
||||
filterClausePattern *regexp.Regexp
|
||||
jointFilterClausePattern *regexp.Regexp
|
||||
)
|
||||
|
||||
func init() {
|
||||
filterClausePattern = regexp.MustCompile(`^(\w+)\.(\w+)\((.*)\)`)
|
||||
jointFilterClausePattern = regexp.MustCompile(`^(\w+)\((\w+)\).(\w+)\.(\w+)\((.*)\)`)
|
||||
}
|
||||
|
||||
func ParseFilterClause(filter string) *SFilterClause {
|
||||
@@ -79,3 +95,21 @@ func ParseFilterClause(filter string) *SFilterClause {
|
||||
fc := SFilterClause{field: matches[1], funcName: matches[2], params: params}
|
||||
return &fc
|
||||
}
|
||||
|
||||
func ParseJointFilterClause(jointFilter string) *SJointFilterClause {
|
||||
matches := jointFilterClausePattern.FindStringSubmatch(jointFilter)
|
||||
if matches == nil {
|
||||
return nil
|
||||
}
|
||||
params := utils.FindWords([]byte(matches[5]), 0)
|
||||
jfc := SJointFilterClause{
|
||||
SFilterClause: SFilterClause{
|
||||
field: matches[3],
|
||||
funcName: matches[4],
|
||||
params: params,
|
||||
},
|
||||
JointModel: matches[1],
|
||||
ReleatedKey: matches[2],
|
||||
}
|
||||
return &jfc
|
||||
}
|
||||
|
||||
+7
-1
@@ -9,12 +9,18 @@ const (
|
||||
STORAGE_NAS = "nas"
|
||||
STORAGE_VSAN = "vsan"
|
||||
|
||||
STORAGE_CLOUD = "cloud"
|
||||
STORAGE_CLOUD_SSD = "cloud_ssd"
|
||||
STORAGE_CLOUD_EFFICIENCY = "cloud_efficiency"
|
||||
|
||||
STORAGE_STANDARD = "standard" //Azure hdd storage type
|
||||
STORAGE_PREMIUM = "premium" //Azure ssd storage type
|
||||
)
|
||||
|
||||
var STORAGE_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_SHEEPDOG,
|
||||
STORAGE_RBD, STORAGE_DOCKER, STORAGE_NAS, STORAGE_VSAN, STORAGE_CLOUD_SSD, STORAGE_CLOUD_EFFICIENCY}
|
||||
STORAGE_RBD, STORAGE_DOCKER, STORAGE_NAS, STORAGE_VSAN,
|
||||
STORAGE_CLOUD, STORAGE_CLOUD_SSD, STORAGE_CLOUD_EFFICIENCY,
|
||||
STORAGE_STANDARD, STORAGE_PREMIUM}
|
||||
|
||||
var LOCAL_STORAGE_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user