fix: auto truncate sql string (#22242)

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
Jian Qiu
2025-03-08 10:45:58 +08:00
committed by GitHub
parent bcfd60e161
commit 6a76123a6a
17 changed files with 158 additions and 22 deletions
+2 -2
View File
@@ -93,14 +93,14 @@ require (
k8s.io/cri-api v0.22.17
k8s.io/klog/v2 v2.20.0
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250227042119-798092148a0c
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250228072304-e6fd389420a9
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256
yunion.io/x/jsonutils v1.0.1-0.20240930100528-1671a2d0d22f
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.4-0.20250128110515-2cde6f625882
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
yunion.io/x/sqlchemy v1.1.3-0.20240926163039-d41512b264e1
yunion.io/x/sqlchemy v1.1.3-0.20250307104108-2f8e0af883e9
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c
)
+4 -4
View File
@@ -1376,8 +1376,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250227042119-798092148a0c h1:nbLq3ttm3Hu3BgFTUaKHdMHiUCIlj0eCOmLjR7teBGM=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250227042119-798092148a0c/go.mod h1:KQ/jWx7bZlmjCE711KEWuvHW/dzpdr/UTlBjjutkj0Y=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250228072304-e6fd389420a9 h1:bweJybvKO9E5WMTI1fgL+1Mu/eUDaod9DXmrqjCwyis=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250228072304-e6fd389420a9/go.mod h1:KQ/jWx7bZlmjCE711KEWuvHW/dzpdr/UTlBjjutkj0Y=
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256 h1:kLKQ6zbgPDQflRwoHFAjxNChcbhXIFgsUVLkJwiXu/8=
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
@@ -1395,7 +1395,7 @@ yunion.io/x/pkg v1.10.4-0.20250128110515-2cde6f625882 h1:Nl4qngZ4mrVe2xsMVrCHLe9
yunion.io/x/pkg v1.10.4-0.20250128110515-2cde6f625882/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM=
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 h1:1KJ3YYinydPHpDEQRXdr/T8SYcKZ5Er+m489H+PnaQ4=
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
yunion.io/x/sqlchemy v1.1.3-0.20240926163039-d41512b264e1 h1:HWPqY1I5JSmM6Sks6FyK9hnq/MjL7FDghM6M8DXHob0=
yunion.io/x/sqlchemy v1.1.3-0.20240926163039-d41512b264e1/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A=
yunion.io/x/sqlchemy v1.1.3-0.20250307104108-2f8e0af883e9 h1:KU8BikBBUJlSkA1Ib01htqaDdzt20K+ezNkTZD8Rxjk=
yunion.io/x/sqlchemy v1.1.3-0.20250307104108-2f8e0af883e9/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A=
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=
+2 -2
View File
@@ -66,7 +66,7 @@ func NewNameValidator(ctx context.Context, manager IModelManager, ownerId mcclie
}
if strings.ContainsAny(name, forbiddenNameChars) {
return errors.Wrapf(errors.ErrInvalidFormat, "name should not contains any of %s", forbiddenNameChars)
return errors.Wrapf(errors.ErrInvalidFormat, "name should not contains any of %q", forbiddenNameChars)
}
uniq, err := isNameUnique(ctx, manager, ownerId, name, uniqValues)
@@ -114,7 +114,7 @@ func alterNameValidator(ctx context.Context, model IModel, name string) error {
}
if strings.ContainsAny(name, forbiddenNameChars) {
return errors.Wrapf(errors.ErrInvalidFormat, "name should not contains any of %s", forbiddenNameChars)
return errors.Wrapf(errors.ErrInvalidFormat, "name should not contains any of %q", forbiddenNameChars)
}
uniq, err := isAlterNameUnique(ctx, model, name)
+2 -2
View File
@@ -1785,7 +1785,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250227042119-798092148a0c
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250228072304-e6fd389420a9
## explicit; go 1.21
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
@@ -1937,7 +1937,7 @@ yunion.io/x/pkg/utils
# yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
## explicit; go 1.12
yunion.io/x/s3cli
# yunion.io/x/sqlchemy v1.1.3-0.20240926163039-d41512b264e1
# yunion.io/x/sqlchemy v1.1.3-0.20250307104108-2f8e0af883e9
## explicit; go 1.17
yunion.io/x/sqlchemy
yunion.io/x/sqlchemy/backends
+3
View File
@@ -1264,6 +1264,9 @@ type IClouduser interface {
AttachPolicy(policyName string, policyType api.TPolicyType) error
DetachPolicy(policyName string, policyType api.TPolicyType) error
SetEnable(password string) error
SetDisable() error
Delete() error
ResetPassword(password string) error
+9
View File
@@ -135,6 +135,15 @@ func (user *SUser) IsConsoleLogin() bool {
return true
}
func (user *SUser) SetDisable() error {
return user.client.DeleteLoginProfile(user.UserName)
}
func (user *SUser) SetEnable(password string) error {
_, err := user.client.CreateLoginProfile(user.UserName, password)
return err
}
func (user *SUser) ResetPassword(password string) error {
return user.client.ResetClouduserPassword(user.UserName, password)
}
+9
View File
@@ -80,6 +80,15 @@ func (user *SUser) IsConsoleLogin() bool {
return true
}
func (user *SUser) SetDisable() error {
return user.client.DeleteLoginProfile(user.UserName)
}
func (user *SUser) SetEnable(password string) error {
_, err := user.client.CreateLoginProfile(user.UserName, password)
return err
}
func (user *SUser) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
groups, err := user.ListGroups()
if err != nil {
+8
View File
@@ -34,3 +34,11 @@ func (self *SBaseClouduser) GetAccessKeys() ([]cloudprovider.SAccessKey, error)
func (self *SBaseClouduser) DeleteAccessKey(accesskey string) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "base DeleteAccessKey")
}
func (self *SBaseClouduser) SetDisable() error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SetDisable")
}
func (self *SBaseClouduser) SetEnable(password string) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SetDisable")
}
+2
View File
@@ -22,6 +22,7 @@ import (
api "yunion.io/x/cloudmux/pkg/apis/cloudid"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
"yunion.io/x/cloudmux/pkg/multicloud/hcso/client/modules"
)
@@ -33,6 +34,7 @@ type SLink struct {
type SClouduser struct {
client *SHuaweiClient
multicloud.SBaseClouduser
Description string
DomainId string
+25 -5
View File
@@ -24,6 +24,7 @@ import (
api "yunion.io/x/cloudmux/pkg/apis/cloudid"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SLink struct {
@@ -34,6 +35,7 @@ type SLink struct {
type SClouduser struct {
client *SHuaweiClient
multicloud.SBaseClouduser
Description string
DomainId string
@@ -96,8 +98,18 @@ func (user *SClouduser) IsConsoleLogin() bool {
return user.Enabled == true
}
func (user *SClouduser) SetDisable() error {
enable := false
return user.client.UpdateUser(user.Id, "", &enable)
}
func (user *SClouduser) SetEnable(password string) error {
enable := true
return user.client.UpdateUser(user.Id, password, &enable)
}
func (user *SClouduser) ResetPassword(password string) error {
return user.client.ResetClouduserPassword(user.Id, password)
return user.client.UpdateUser(user.Id, password, nil)
}
// https://console.huaweicloud.com/apiexplorer/#/openapi/IAM/doc?api=KeystoneDeleteUser
@@ -200,11 +212,19 @@ func (self *SHuaweiClient) CreateClouduser(name, password, desc string) (*SCloud
}
// https://console.huaweicloud.com/apiexplorer/#/openapi/IAM/doc?api=UpdateUser
func (self *SHuaweiClient) ResetClouduserPassword(id, password string) error {
func (self *SHuaweiClient) UpdateUser(id, password string, enable *bool) error {
params := map[string]interface{}{}
if len(password) > 0 {
params["password"] = password
}
if enable != nil {
params["enabled"] = false
if *enable {
params["enabled"] = true
}
}
_, err := self.put(SERVICE_IAM, "", "OS-USER/users/"+id, map[string]interface{}{
"user": map[string]interface{}{
"password": password,
},
"user": params,
})
return err
}
+22 -5
View File
@@ -83,12 +83,22 @@ func (user *SUser) IsConsoleLogin() bool {
return user.ConsoleLogin == 1
}
func (user *SUser) SetDisable() error {
login := false
return user.client.UpdateUser(user.Name, "", &login)
}
func (user *SUser) SetEnable(password string) error {
login := true
return user.client.UpdateUser(user.Name, password, &login)
}
func (user *SUser) Delete() error {
return user.client.DeleteUser(user.Name)
}
func (user *SUser) ResetPassword(password string) error {
return user.client.UpdateUser(user.Name, password)
return user.client.UpdateUser(user.Name, password, nil)
}
func (user *SUser) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
@@ -243,11 +253,18 @@ func (self *SQcloudClient) AddUser(name, password, desc string, consoleLogin boo
return user, nil
}
func (self *SQcloudClient) UpdateUser(name, password string) error {
func (self *SQcloudClient) UpdateUser(name, password string, login *bool) error {
params := map[string]string{
"Name": name,
"ConsoleLogin": "1",
"Password": password,
"Name": name,
}
if len(password) > 0 {
params["Password"] = password
}
if login != nil {
params["ConsoleLogin"] = "0"
if *login {
params["ConsoleLogin"] = "1"
}
}
_, err := self.camRequest("UpdateUser", params)
if err != nil {
+17
View File
@@ -90,6 +90,15 @@ func (user *SUser) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
return ret, nil
}
func (user *SUser) SetDisable() error {
return user.client.DeleteLoginProfile(user.UserName)
}
func (user *SUser) SetEnable(password string) error {
login := true
return user.client.UpdateLoginProfile(user.UserName, password, &login)
}
func (user *SUser) IsConsoleLogin() bool {
profile, err := user.client.GetLoginProfile(user.UserName)
if err != nil {
@@ -225,6 +234,14 @@ func (self *SVolcEngineClient) CreateLoginProfile(name, password string, loginAl
return err
}
func (self *SVolcEngineClient) DeleteLoginProfile(name string) error {
params := map[string]string{
"UserName": name,
}
_, err := self.iamRequest("", "DeleteLoginProfile", params)
return err
}
func (self *SVolcEngineClient) UpdateLoginProfile(name, password string, loginAllowd *bool) error {
params := map[string]string{
"UserName": name,
+10
View File
@@ -72,6 +72,8 @@ type IColumnSpec interface {
// IsNumeric returns whether this column is a numeric type column, e.g. integer or float
IsNumeric() bool
GetWidth() int
// ConvertFromString returns the SQL representation of a value in string format for this column
ConvertFromString(str string) interface{}
@@ -304,6 +306,10 @@ func (c *SBaseColumn) SetColIndex(idx int) {
c.colIndex = idx
}
func (c *SBaseColumn) GetWidth() int {
return 0
}
// NewBaseColumn returns an instance of SBaseColumn
func NewBaseColumn(name string, sqltype string, tagmap map[string]string, isPointer bool) SBaseColumn {
var val string
@@ -382,6 +388,10 @@ func (c *SBaseWidthColumn) ColType() string {
return c.sqlType
}
func (c *SBaseWidthColumn) GetWidth() int {
return c.width
}
// NewBaseWidthColumn return an instance of SBaseWidthColumn
func NewBaseWidthColumn(name string, sqltype string, tagmap map[string]string, isPointer bool) SBaseWidthColumn {
width := 0
+7
View File
@@ -158,6 +158,13 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes
// not empty
if !gotypes.IsNil(ov) && (!c.IsZero(ov) || (!c.IsPointer() && !c.IsText())) && !isAutoInc {
// validate text width
if c.IsString() && c.GetWidth() > 0 {
newStr, ok := ov.(string)
if ok && len(newStr) > c.GetWidth() {
ov = newStr[:c.GetWidth()]
}
}
v := c.ConvertFromValue(ov)
values = append(values, v)
names = append(names, fmt.Sprintf("%s%s%s", qChar, k, qChar))
+7
View File
@@ -111,6 +111,13 @@ func (t *STableSpec) InsertBatch(dataList []interface{}) error {
params = append(params, nil)
}
} else {
// validate text width
if col.IsString() && col.GetWidth() > 0 {
newStr, ok := ov.(string)
if ok && len(newStr) > col.GetWidth() {
ov = newStr[:col.GetWidth()]
}
}
params = append(params, col.ConvertFromValue(ov))
}
}
+22 -2
View File
@@ -195,11 +195,30 @@ func queryString(tq *SQuery, tmpFields ...IQueryField) string {
}
if tq.groupBy != nil && len(tq.groupBy) > 0 {
buf.WriteString(" GROUP BY ")
for i, f := range tq.groupBy {
groupByFields := make(map[string]IQueryField)
for i := range tq.groupBy {
f := tq.groupBy[i]
if _, ok := groupByFields[f.Reference()]; ok {
continue
}
if i > 0 {
buf.WriteString(", ")
}
buf.WriteString(f.Reference())
groupByFields[f.Reference()] = f
}
// DAMENG SQL Compatibility, all order by fields should be in group by
for i := range tq.orderBy {
f := tq.orderBy[i]
if _, ok := groupByFields[f.field.Reference()]; ok {
continue
}
if ff, ok := f.field.(IFunctionQueryField); ok && ff.IsAggregate() {
continue
}
buf.WriteString(", ")
buf.WriteString(f.field.Reference())
groupByFields[f.field.Reference()] = f.field
}
}
/*if tq.having != nil {
@@ -208,7 +227,8 @@ func queryString(tq *SQuery, tmpFields ...IQueryField) string {
}*/
if tq.orderBy != nil && len(tq.orderBy) > 0 {
buf.WriteString(" ORDER BY ")
for i, f := range tq.orderBy {
for i := range tq.orderBy {
f := tq.orderBy[i]
if i > 0 {
buf.WriteString(", ")
}
+7
View File
@@ -198,6 +198,13 @@ func (us *SUpdateSession) SaveUpdateSql(dt interface{}) (*SUpdateSQLResult, erro
if gotypes.IsNil(udif.new) {
colsets = append(colsets, fmt.Sprintf("%s%s%s = NULL", qChar, udif.col.Name(), qChar))
} else {
// validate text length
if udif.col.IsString() && udif.col.GetWidth() > 0 {
newStr, ok := udif.new.(string)
if ok && len(newStr) > udif.col.GetWidth() {
udif.new = newStr[:udif.col.GetWidth()]
}
}
colsets = append(colsets, fmt.Sprintf("%s%s%s = ?", qChar, udif.col.Name(), qChar))
vars = append(vars, udif.col.ConvertFromValue(udif.new))
}