diff --git a/go.mod b/go.mod index 48702e2147..5d31350a47 100644 --- a/go.mod +++ b/go.mod @@ -152,7 +152,7 @@ require ( yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051 yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d yunion.io/x/pkg v0.0.0-20190726033806-b564cfdcc224 - yunion.io/x/s3cli v0.0.0-20190812030153-814f1e636a0a - yunion.io/x/sqlchemy v0.0.0-20190704155352-6aff6c803fda + yunion.io/x/s3cli v0.0.0-20190812034537-1e65a6651a3e + yunion.io/x/sqlchemy v0.0.0-20190813100902-cfa59aeabbfe yunion.io/x/structarg v0.0.0-20190809075558-115bed041de3 ) diff --git a/go.sum b/go.sum index 8953f9813b..f070f6692e 100644 --- a/go.sum +++ b/go.sum @@ -585,9 +585,9 @@ yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf h1:OsKC+2ghZHwp+Ztm/MwKlLKKRi yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/pkg v0.0.0-20190726033806-b564cfdcc224 h1:dAeUov/CtKcPaOapGVG7+NRqmUF2fr2O3Onb+ID5HS4= yunion.io/x/pkg v0.0.0-20190726033806-b564cfdcc224/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= -yunion.io/x/s3cli v0.0.0-20190812030153-814f1e636a0a h1:7E013HqvvP2Q7PExgdfTPGEhYcfpz/0L2WotfCG70dg= -yunion.io/x/s3cli v0.0.0-20190812030153-814f1e636a0a/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo= -yunion.io/x/sqlchemy v0.0.0-20190704155352-6aff6c803fda h1:i+/3Hh+kVmPZM1P+j3wfViEzb0XlttWyNvDSYA5DDDU= -yunion.io/x/sqlchemy v0.0.0-20190704155352-6aff6c803fda/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI= +yunion.io/x/s3cli v0.0.0-20190812034537-1e65a6651a3e h1:Jk82txl4vaL/MoVV3+GweEcCmLOcqo5XYF8tlBD/1hY= +yunion.io/x/s3cli v0.0.0-20190812034537-1e65a6651a3e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo= +yunion.io/x/sqlchemy v0.0.0-20190813100902-cfa59aeabbfe h1:gslRYwVFAQI29PZL56mfBe+zpgbtIMSL1zSEnBbF1bI= +yunion.io/x/sqlchemy v0.0.0-20190813100902-cfa59aeabbfe/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI= yunion.io/x/structarg v0.0.0-20190809075558-115bed041de3 h1:bfC8EhXYvyGYldRWlzxiCM39Zfj3s3+zham9mW2h2LE= yunion.io/x/structarg v0.0.0-20190809075558-115bed041de3/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng= diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index e445897ea1..5bc035f464 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -1472,25 +1472,36 @@ func (manager *SGuestManager) ListItemExportKeys(ctx context.Context, q *sqlchem guestIpsQuery := GuestnetworkManager.Query("guest_id").GroupBy("guest_id") guestIpsQuery.AppendField(sqlchemy.GROUP_CONCAT("concat_ip_addr", guestIpsQuery.Field("ip_addr"))) ipsSubQuery := guestIpsQuery.SubQuery() - guestIpsQuery.DebugQuery() q.LeftJoin(ipsSubQuery, sqlchemy.Equals(q.Field("id"), ipsSubQuery.Field("guest_id"))) q.AppendField(ipsSubQuery.Field("concat_ip_addr")) } + + if utils.IsInStringArray("user_tags", keys) { + guestUserTagsQuery := db.Metadata.Query().Startswith("id", "server::"). + Startswith("key", db.USER_TAG_PREFIX).GroupBy("id") + guestUserTagsQuery.AppendField(sqlchemy.SubStr("guest_id", guestUserTagsQuery.Field("id"), len("server::")+1, 0)) + guestUserTagsQuery.AppendField( + sqlchemy.GROUP_CONCAT("user_tags", sqlchemy.CONCAT("", + guestUserTagsQuery.Field("key"), + guestUserTagsQuery.Field("value"), + ))) + subQ := guestUserTagsQuery.SubQuery() + q.LeftJoin(subQ, sqlchemy.Equals(q.Field("id"), subQ.Field("guest_id"))) + q.AppendField(subQ.Field("user_tags")) + } + if utils.IsInStringArray("disk", keys) { guestDisksQuery := GuestdiskManager.Query("guest_id", "disk_id").GroupBy("guest_id") diskQuery := DiskManager.Query("id", "disk_size").SubQuery() guestDisksQuery.Join(diskQuery, sqlchemy.Equals(diskQuery.Field("id"), guestDisksQuery.Field("disk_id"))) guestDisksQuery.AppendField(sqlchemy.SUM("disk_size", diskQuery.Field("disk_size"))) guestDisksSubQuery := guestDisksQuery.SubQuery() - guestDisksSubQuery.DebugQuery() - q.LeftJoin(guestDisksSubQuery, sqlchemy.Equals(q.Field("id"), guestDisksSubQuery. - Field("guest_id"))) + q.LeftJoin(guestDisksSubQuery, sqlchemy.Equals(q.Field("id"), guestDisksSubQuery.Field("guest_id"))) q.AppendField(guestDisksSubQuery.Field("disk_size")) } if utils.IsInStringArray("eip", keys) { eipsQuery := ElasticipManager.Query("associate_id", "ip_addr").Equals("associate_type", "server").GroupBy("associate_id") eipsSubQuery := eipsQuery.SubQuery() - eipsSubQuery.DebugQuery() q.LeftJoin(eipsSubQuery, sqlchemy.Equals(q.Field("id"), eipsSubQuery.Field("associate_id"))) q.AppendField(eipsSubQuery.Field("ip_addr", "eip")) } @@ -1563,6 +1574,9 @@ func (manager *SGuestManager) GetExportExtraKeys(ctx context.Context, query json if manager, ok := rowMap["manager"]; ok && len(manager) > 0 { res.Set("manager", jsonutils.NewString(manager)) } + if userTags, ok := rowMap["user_tags"]; ok && len(userTags) > 0 { + res.Set("user_tags", jsonutils.NewString(userTags)) + } if utils.IsInStringArray("tenant", keys) { if projectId, ok := rowMap["tenant_id"]; ok { tenant, err := db.TenantCacheManager.FetchTenantById(ctx, projectId) diff --git a/vendor/modules.txt b/vendor/modules.txt index 4e05df7ade..3b3b4b7f56 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -798,9 +798,9 @@ yunion.io/x/pkg/util/prometheus yunion.io/x/pkg/prettytable yunion.io/x/pkg/util/runtime yunion.io/x/pkg/util/clock -# yunion.io/x/s3cli v0.0.0-20190812030153-814f1e636a0a +# yunion.io/x/s3cli v0.0.0-20190812034537-1e65a6651a3e yunion.io/x/s3cli -# yunion.io/x/sqlchemy v0.0.0-20190704155352-6aff6c803fda +# yunion.io/x/sqlchemy v0.0.0-20190813100902-cfa59aeabbfe yunion.io/x/sqlchemy # yunion.io/x/structarg v0.0.0-20190809075558-115bed041de3 yunion.io/x/structarg diff --git a/vendor/yunion.io/x/s3cli/OWNERS b/vendor/yunion.io/x/s3cli/OWNERS new file mode 100644 index 0000000000..7139f9d3ba --- /dev/null +++ b/vendor/yunion.io/x/s3cli/OWNERS @@ -0,0 +1,12 @@ +# See the OWNERS docs at https://go.k8s.io/owners +reviewers: + - swordqiu + - yousong + - wanyaoqi + - Zexi + - ioito + - tb365 +approvers: + - swordqiu + - yousong + - Zexi diff --git a/vendor/yunion.io/x/sqlchemy/functions.go b/vendor/yunion.io/x/sqlchemy/functions.go index 449966a2a7..26ead1dd72 100644 --- a/vendor/yunion.io/x/sqlchemy/functions.go +++ b/vendor/yunion.io/x/sqlchemy/functions.go @@ -49,11 +49,42 @@ func (ff *SFunctionField) Label(label string) IQueryField { return ff } -func NewFunctionField(name string, funcexp string, fields ...IQueryField) SFunctionField { - ff := SFunctionField{function: funcexp, alias: name, fields: fields} +type SFunctionFieldWithoutAlias struct { + fields []IQueryField + function string +} + +func (ff *SFunctionFieldWithoutAlias) Expression() string { + fieldRefs := make([]interface{}, 0) + for _, f := range ff.fields { + fieldRefs = append(fieldRefs, f.Reference()) + } + return fmt.Sprintf(ff.function, fieldRefs...) +} + +func (ff *SFunctionFieldWithoutAlias) Name() string { + return ff.Expression() +} + +func (ff *SFunctionFieldWithoutAlias) Reference() string { + return ff.Expression() +} + +func (ff *SFunctionFieldWithoutAlias) Label(label string) IQueryField { + if len(label) > 0 { + return &SFunctionField{ff.fields, ff.function, label} + } return ff } +func NewFunctionField(name string, funcexp string, fields ...IQueryField) IQueryField { + if len(name) > 0 { + return &SFunctionField{function: funcexp, alias: name, fields: fields} + } else { + return &SFunctionFieldWithoutAlias{fields: fields, function: funcexp} + } +} + func COUNT(name string, field ...IQueryField) IQueryField { var expr string if len(field) == 0 { @@ -61,33 +92,27 @@ func COUNT(name string, field ...IQueryField) IQueryField { } else { expr = "COUNT(%s)" } - ff := NewFunctionField(name, expr, field...) - return &ff + return NewFunctionField(name, expr, field...) } func MAX(name string, field IQueryField) IQueryField { - ff := NewFunctionField(name, "MAX(%s)", field) - return &ff + return NewFunctionField(name, "MAX(%s)", field) } func SUM(name string, field IQueryField) IQueryField { - ff := NewFunctionField(name, "SUM(%s)", field) - return &ff + return NewFunctionField(name, "SUM(%s)", field) } func DISTINCT(name string, field IQueryField) IQueryField { - ff := NewFunctionField(name, "DISTINCT(%s)", field) - return &ff + return NewFunctionField(name, "DISTINCT(%s)", field) } func GROUP_CONCAT(name string, field IQueryField) IQueryField { - ff := NewFunctionField(name, "GROUP_CONCAT(%s)", field) - return &ff + return NewFunctionField(name, "GROUP_CONCAT(%s)", field) } func REPLACE(name string, field IQueryField, old string, new string) IQueryField { - ff := NewFunctionField(name, fmt.Sprintf(`REPLACE(%s, "%s", "%s")`, "%s", old, new), field) - return &ff + return NewFunctionField(name, fmt.Sprintf(`REPLACE(%s, "%s", "%s")`, "%s", old, new), field) } type SStringField struct { @@ -123,6 +148,25 @@ func CONCAT(name string, fields ...IQueryField) IQueryField { for i := 0; i < len(fields); i++ { params = append(params, "%s") } - ff := NewFunctionField(name, `CONCAT(`+strings.Join(params, ",")+`)`, fields...) - return &ff + return NewFunctionField(name, `CONCAT(`+strings.Join(params, ",")+`)`, fields...) +} + +func SubStr(name string, field IQueryField, pos, length int) IQueryField { + var rightStr string + if length <= 0 { + rightStr = fmt.Sprintf("%d)", pos) + } else { + rightStr = fmt.Sprintf("%d, %d)", pos, length) + } + return NewFunctionField(name, `SUBSTR(%s, `+rightStr, field) +} + +func OR_Val(name string, field IQueryField, v interface{}) IQueryField { + rightStr := fmt.Sprintf("|%v", v) + return NewFunctionField(name, "%s"+rightStr, field) +} + +func AND_Val(name string, field IQueryField, v interface{}) IQueryField { + rightStr := fmt.Sprintf("&%v", v) + return NewFunctionField(name, "%s"+rightStr, field) }