fix: network ip match recode to fix dameng INET_ATON support (#19654)

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
Jian Qiu
2024-03-06 03:08:17 +08:00
committed by GitHub
co-authored by Qiu Jian
parent 0d677954af
commit e4b5bd9979
13 changed files with 94 additions and 82 deletions
+2 -2
View File
@@ -91,11 +91,11 @@ require (
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240305034450-d50f47051d06
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32
yunion.io/x/jsonutils v1.0.1-0.20240203102553-4096f103b401
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
yunion.io/x/pkg v1.10.1-0.20240303050651-73685b15a96e
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e
yunion.io/x/sqlchemy v1.1.3-0.20240304110946-16faa82225e6
yunion.io/x/sqlchemy v1.1.3-0.20240305180726-ccd03e6aa837
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c
)
+4 -4
View File
@@ -1213,8 +1213,8 @@ yunion.io/x/jsonutils v1.0.1-0.20240203102553-4096f103b401 h1:4l6ELFSQ0MBVInscZ8
yunion.io/x/jsonutils v1.0.1-0.20240203102553-4096f103b401/go.mod h1:VK4Z93dgiKgAijcSqbMKmGaBMJuHulR16Hz4K015ZPo=
yunion.io/x/log v0.0.0-20190514041436-04ce53b17c6b/go.mod h1:+gauLs73omeJAPlsXcevLsJLKixV+sR/E7WSYTSx1fE=
yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361 h1:c5LyNdhbvBe/92pXs9jgXOU/S+RgYh/DHe538LpT/Mo=
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91 h1:inY5o3LDa/zgsIZuPN0HmpzKIsu/lLgsBmMttuDPGj4=
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 h1:Hu/4ERvoWaN6aiFs4h4/yvVBMeVzb3eDaYTxkVx9Kdo=
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc=
yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
@@ -1223,7 +1223,7 @@ yunion.io/x/pkg v1.10.1-0.20240303050651-73685b15a96e h1:NuYu+z0dOT93aoNjg3W3PkL
yunion.io/x/pkg v1.10.1-0.20240303050651-73685b15a96e/go.mod h1:ksCJVQ+DwKrJ5QBEoU8pzrDFfDaZVAFH/iJ6yQCYxJk=
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo=
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
yunion.io/x/sqlchemy v1.1.3-0.20240304110946-16faa82225e6 h1:3R34JW8CxuweUn4mCrFMSTwU5Njwh5aCB5x9x6l5GBA=
yunion.io/x/sqlchemy v1.1.3-0.20240304110946-16faa82225e6/go.mod h1:5W8ghvJ4TNt/r2yDjjD3i4QsZgIiJX45dhRQBGWPHsQ=
yunion.io/x/sqlchemy v1.1.3-0.20240305180726-ccd03e6aa837 h1:2KhiZJdbKVK6ksl542z5BzDsD+bgpHEtYHCEuA8Y48A=
yunion.io/x/sqlchemy v1.1.3-0.20240305180726-ccd03e6aa837/go.mod h1:5W8ghvJ4TNt/r2yDjjD3i4QsZgIiJX45dhRQBGWPHsQ=
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c h1:QuLab2kSRECZRxo4Lo2KcYn6XjQFDGaZ1+x0pYDVVwQ=
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
+41 -19
View File
@@ -2633,31 +2633,53 @@ func (manager *SNetworkManager) ListItemFilter(
if len(ips) > 0 {
conditions := []sqlchemy.ICondition{}
for _, ip := range ips {
if len(ip) == 0 {
for _, ipstr := range ips {
if len(ipstr) == 0 {
continue
}
ipIa, err := parseIpToIntArray(ip)
if err != nil {
return nil, err
}
ipSa := []string{"0", "0", "0", "0"}
for i := range ipIa {
ipSa[i] = strconv.Itoa(ipIa[i])
}
fullIp := strings.Join(ipSa, ".")
ipField := sqlchemy.INET_ATON(sqlchemy.NewStringField(fullIp))
ipStart := sqlchemy.INET_ATON(q.Field("guest_ip_start"))
ipEnd := sqlchemy.INET_ATON(q.Field("guest_ip_end"))
var ipCondtion sqlchemy.ICondition
if exactIpMatch {
ipCondtion = sqlchemy.Between(ipField, ipStart, ipEnd)
if ip4Addr, err := netutils.NewIPV4Addr(ipstr); err == nil {
// ipv4 address, exactly
ipStart := sqlchemy.INET_ATON(q.Field("guest_ip_start"))
ipEnd := sqlchemy.INET_ATON(q.Field("guest_ip_end"))
ipCondtion = sqlchemy.AND(
sqlchemy.GE(ipEnd, uint32(ip4Addr)),
sqlchemy.LE(ipStart, uint32(ip4Addr)),
)
if !exactIpMatch {
ipCondtion = sqlchemy.OR(
ipCondtion,
sqlchemy.Contains(q.Field("guest_ip_start"), ipstr),
sqlchemy.Contains(q.Field("guest_ip_end"), ipstr),
)
}
} else if ip6Addr, err := netutils.NewIPV6Addr(ipstr); err == nil {
// ipv6 address, exactly
ipStart := q.Field("guest_ip6_start")
ipEnd := q.Field("guest_ip6_end")
ipCondtion = sqlchemy.AND(
sqlchemy.GE(ipEnd, ip6Addr.String()),
sqlchemy.LE(ipStart, ip6Addr.String()),
)
if !exactIpMatch {
ipCondtion = sqlchemy.OR(
ipCondtion,
sqlchemy.Contains(q.Field("guest_ip6_start"), ipstr),
sqlchemy.Contains(q.Field("guest_ip6_end"), ipstr),
)
}
} else {
ipCondtion = sqlchemy.OR(sqlchemy.Between(ipField, ipStart, ipEnd), sqlchemy.Contains(q.Field("guest_ip_start"), ip), sqlchemy.Contains(q.Field("guest_ip_end"), ip))
ipCondtion = sqlchemy.OR(
sqlchemy.Contains(q.Field("guest_ip_start"), ipstr),
sqlchemy.Contains(q.Field("guest_ip_end"), ipstr),
sqlchemy.Contains(q.Field("guest_ip6_start"), ipstr),
sqlchemy.Contains(q.Field("guest_ip6_end"), ipstr),
)
}
conditions = append(conditions, ipCondtion)
}
q = q.Filter(sqlchemy.OR(conditions...))
+2 -2
View File
@@ -1561,7 +1561,7 @@ yunion.io/x/executor/server
# yunion.io/x/jsonutils v1.0.1-0.20240203102553-4096f103b401
## explicit; go 1.18
yunion.io/x/jsonutils
# yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361
# yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
## explicit; go 1.12
yunion.io/x/log
yunion.io/x/log/hooks
@@ -1626,7 +1626,7 @@ yunion.io/x/pkg/utils
# yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e
## explicit; go 1.12
yunion.io/x/s3cli
# yunion.io/x/sqlchemy v1.1.3-0.20240304110946-16faa82225e6
# yunion.io/x/sqlchemy v1.1.3-0.20240305180726-ccd03e6aa837
## explicit; go 1.17
yunion.io/x/sqlchemy
yunion.io/x/sqlchemy/backends
+3
View File
@@ -17,6 +17,7 @@ package log
import (
"runtime"
"runtime/debug"
"sync"
"github.com/sirupsen/logrus"
@@ -134,10 +135,12 @@ func Errorln(args ...interface{}) {
}
func Fatalf(format string, args ...interface{}) {
debug.PrintStack()
logrus.Fatalf(format, args...)
}
func Fatalln(args ...interface{}) {
debug.PrintStack()
logrus.Fatalln(args...)
}
+7
View File
@@ -16,6 +16,7 @@ package dameng
import (
"fmt"
"log"
"reflect"
"strconv"
"strings"
@@ -84,11 +85,17 @@ func (dameng *SDamengBackend) PrepareInsertOrUpdateSQL(ts sqlchemy.ITableSpec, i
selectValues := make([]string, 0, len(insertColNames))
onConditions := make([]string, 0, len(onPrimaryCols))
colNameMap := make(map[string]struct{})
for i := range insertColNames {
colName := strings.Trim(insertColNames[i], "'\"")
colNameMap[colName] = struct{}{}
selectValues = append(selectValues, fmt.Sprintf("%s AS \"%s\"", insertFields[i], colName))
}
for _, primary := range onPrimaryCols {
colName := strings.Trim(primary, "'\"")
if _, ok := colNameMap[colName]; !ok {
log.Fatalf("primary colume %s missing from insert columes for table %s", colName, ts.Name())
}
onConditions = append(onConditions, fmt.Sprintf("T1.%s=T2.%s", primary, primary))
}
for i := range updateSetCols {
+21 -2
View File
@@ -21,6 +21,25 @@ import (
)
// GROUP_CONCAT2 represents the SQL function GROUP_CONCAT
func (mysql *SDamengBackend) GROUP_CONCAT2(name string, sep string, field sqlchemy.IQueryField) sqlchemy.IQueryField {
return sqlchemy.NewFunctionField(name, true, fmt.Sprintf("REPLACE(WM_CONCAT(%%s), ',', '%s')", sep), field)
func (dameng *SDamengBackend) GROUP_CONCAT2(name string, sep string, field sqlchemy.IQueryField) sqlchemy.IQueryField {
if sep == "," {
return sqlchemy.NewFunctionField(name, true, `WM_CONCAT(%s)`, field)
} else {
return sqlchemy.NewFunctionField(name, true, fmt.Sprintf("REPLACE(WM_CONCAT(%%s), ',', '%s')", sep), field)
}
}
// INET_ATON represents the SQL function INET_ATON
func (dameng *SDamengBackend) INET_ATON(field sqlchemy.IQueryField) sqlchemy.IQueryField {
expr := ""
vars := make([]sqlchemy.IQueryField, 0)
expr += `TO_NUMBER(SUBSTR(%s,1,INSTR(%s,'.')-1))*POWER(256,3)+`
vars = append(vars, field, field)
expr += `TO_NUMBER(SUBSTR(%s,INSTR(%s,'.')+1,INSTR(%s,'.',1,2)-INSTR(%s,'.')-1))*POWER(256,2)+`
vars = append(vars, field, field, field, field)
expr += `TO_NUMBER(SUBSTR(%s,INSTR(%s,'.',1,2)+1,INSTR(%s,'.',1,3)-INSTR(%s,'.',1,2)-1))*256+`
vars = append(vars, field, field, field, field)
expr += `TO_NUMBER(SUBSTR(%s,INSTR(%s,'.',1,3)+1))`
vars = append(vars, field, field)
return sqlchemy.NewFunctionField("", false, expr, vars...)
}
+6 -29
View File
@@ -17,8 +17,6 @@ package sqlchemy
import (
"fmt"
"strings"
"yunion.io/x/log"
)
// IFunctionQueryField is a special type of field that is an aggregate function
@@ -74,12 +72,6 @@ func (ff *SFunctionFieldBase) Reference() string {
// Expression implementation of SFunctionFieldBase for IQueryField
func (ff *SFunctionFieldBase) Expression() string {
if len(ff.alias) > 0 {
qChar := ff.getQuoteChar()
// add alias
return fmt.Sprintf("%s AS %s%s%s", ff.expression(), qChar, ff.alias, qChar)
}
// no alias
return ff.expression()
}
@@ -116,12 +108,7 @@ type sExprFunction struct {
func (ff *sExprFunction) expression() string {
fieldRefs := make([]interface{}, 0)
for _, f := range ff.fields {
switch tf := f.(type) {
case *SFunctionFieldBase:
fieldRefs = append(fieldRefs, tf.expression())
default:
fieldRefs = append(fieldRefs, tf.Reference())
}
fieldRefs = append(fieldRefs, f.Expression())
}
return fmt.Sprintf(ff.function, fieldRefs...)
}
@@ -142,9 +129,9 @@ func (ff *sExprFunction) database() *SDatabase {
return db
}
}
if ff.function != "COUNT(*)" {
log.Debugf("no fields function? %s", ff.expression())
}
// if ff.function != "COUNT(*)" {
// log.Debugf("no fields function? %s", ff.expression())
// }
return nil
}
@@ -224,12 +211,7 @@ type SConstField struct {
// Expression implementation of SConstField for IQueryField
func (s *SConstField) Expression() string {
name := s.Name()
if len(name) == 0 {
return s.Reference()
} else {
return fmt.Sprintf("%s AS %s", s.Reference(), name)
}
return s.Reference()
}
// Name implementation of SConstField for IQueryField
@@ -278,12 +260,7 @@ type SStringField struct {
// Expression implementation of SStringField for IQueryField
func (s *SStringField) Expression() string {
name := s.Name()
if len(name) == 0 {
return s.Reference()
} else {
return fmt.Sprintf("%s AS %s", s.Reference(), name)
}
return s.Reference()
}
// Name implementation of SStringField for IQueryField
+3
View File
@@ -169,6 +169,9 @@ func queryString(tq *SQuery, tmpFields ...IQueryField) string {
// normal
buf.WriteString(f.Expression())
}
if f.Name() != "" {
buf.WriteString(fmt.Sprintf(" AS %s%s%s", qChar, f.Name(), qChar))
}
}
buf.WriteString(" FROM ")
buf.WriteString(fmt.Sprintf("%s AS %s%s%s", tq.from.Expression(), qChar, tq.from.Alias(), qChar))
+1 -6
View File
@@ -25,12 +25,7 @@ type sQueryField struct {
// the string after select
func (sqf *sQueryField) Expression() string {
qChar := sqf.from.database().backend.QuoteChar()
alias := sqf.name
if len(sqf.alias) > 0 {
alias = sqf.alias
}
return fmt.Sprintf("%s%s%s.%s%s%s AS %s%s%s", qChar, sqf.from.Alias(), qChar, qChar, sqf.name, qChar, qChar, alias, qChar)
return fmt.Sprintf("%s%s%s.%s%s%s", qChar, sqf.from.Alias(), qChar, qChar, sqf.name, qChar)
}
// the name of thie field
+2 -7
View File
@@ -31,12 +31,7 @@ type SSubQueryField struct {
// Expression implementation of SSubQueryField for IQueryField
func (sqf *SSubQueryField) Expression() string {
qChar := sqf.query.database().backend.QuoteChar()
alias := sqf.field.Name()
if len(sqf.alias) > 0 {
alias = sqf.alias
}
return fmt.Sprintf("%s%s%s.%s%s%s AS %s%s%s", qChar, sqf.query.alias, qChar, qChar, sqf.field.Name(), qChar, qChar, alias, qChar)
return fmt.Sprintf("%s%s%s.%s%s%s", qChar, sqf.query.alias, qChar, qChar, sqf.field.Name(), qChar)
}
// Name implementation of SSubQueryField for IQueryField
@@ -125,7 +120,7 @@ func (sq *SSubQuery) findField(id string) IQueryField {
func (sq *SSubQuery) Field(id string, alias ...string) IQueryField {
f := sq.field(id, alias...)
if f == nil {
log.Errorf("subquery %s AS %s cannot find field %s", sq.query.String(), sq.alias, id)
log.Errorf("subquery %s as %s cannot find field %s", sq.query.String(), sq.alias, id)
}
return f
}
+1 -5
View File
@@ -355,12 +355,8 @@ func (tbl *STable) Variables() []interface{} {
// Expression implementation of STableField for IQueryField
func (c *STableField) Expression() string {
alias := c.spec.Name()
if len(c.alias) > 0 {
alias = c.alias
}
qChar := c.database().backend.QuoteChar()
return fmt.Sprintf("%s%s%s.%s%s%s AS %s%s%s", qChar, c.table.Alias(), qChar, qChar, c.spec.Name(), qChar, qChar, alias, qChar)
return fmt.Sprintf("%s%s%s.%s%s%s", qChar, c.table.Alias(), qChar, qChar, c.spec.Name(), qChar)
}
// Name implementation of STableField for IQueryField
+1 -6
View File
@@ -33,12 +33,7 @@ type SUnionQueryField struct {
// Expression implementation of SUnionQueryField for IQueryField
func (sqf *SUnionQueryField) Expression() string {
qChar := sqf.union.database().backend.QuoteChar()
alias := sqf.name
if len(sqf.alias) > 0 {
alias = sqf.alias
}
return fmt.Sprintf("%s%s%s.%s%s%s AS %s%s%s", qChar, sqf.union.Alias(), qChar, qChar, sqf.name, qChar, qChar, alias, qChar)
return fmt.Sprintf("%s%s%s.%s%s%s", qChar, sqf.union.Alias(), qChar, qChar, sqf.name, qChar)
}
// Name implementation of SUnionQueryField for IQueryField