diff --git a/go.mod b/go.mod index b64eed8854..c3e0d9b104 100644 --- a/go.mod +++ b/go.mod @@ -88,14 +88,14 @@ require ( k8s.io/client-go v0.19.3 k8s.io/cluster-bootstrap v0.19.3 moul.io/http2curl/v2 v2.3.0 - yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240826095554-2919a9d956e4 + yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240827090500-d1bed3a44db5 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.20240305175729-7cf2d6cd5a91 yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 yunion.io/x/pkg v1.10.1-0.20240826001854-ac73b70d75b7 yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e - yunion.io/x/sqlchemy v1.1.3-0.20240823033059-be6fe90dab22 + yunion.io/x/sqlchemy v1.1.3-0.20240831153043-4030cea8d4b9 yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c ) diff --git a/go.sum b/go.sum index ae6fb84e2c..1162a3b577 100644 --- a/go.sum +++ b/go.sum @@ -756,8 +756,6 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zexi/influxql-to-metricsql v0.0.7 h1:t2Kp6neknnOnszNl3mLteK4dSmXWglfI1JYUtRWTmyQ= -github.com/zexi/influxql-to-metricsql v0.0.7/go.mod h1:PyRRM+3Zrzzig6J4okYLeSv+/d+5GaL5ccBaUKQABNs= github.com/zexi/influxql-to-metricsql v0.0.8 h1:DIzXVffcpWGgW6AHdK8exHXKyh6dFNXuBrYdFStyFIQ= github.com/zexi/influxql-to-metricsql v0.0.8/go.mod h1:PyRRM+3Zrzzig6J4okYLeSv+/d+5GaL5ccBaUKQABNs= go.etcd.io/etcd/api/v3 v3.5.0 h1:GsV3S+OfZEOCNXdtNkBSR7kgLobAa/SO6tCxRa0GAYw= @@ -1211,8 +1209,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.20240826095554-2919a9d956e4 h1:a1eSeDvUi7jkcCPbgAQnnjWTn9zCwdYUqRWhCAobnxY= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240826095554-2919a9d956e4/go.mod h1:iLoBHVR2Eur/1WJSGcbZaEwpzh/iqXvbFCsX9/xt8CI= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240827090500-d1bed3a44db5 h1:pBDwFbDZ+CqRopliQp6SysWnUgHjd67/Z1btDI4tH74= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240827090500-d1bed3a44db5/go.mod h1:iLoBHVR2Eur/1WJSGcbZaEwpzh/iqXvbFCsX9/xt8CI= yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug= yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634= @@ -1230,7 +1228,7 @@ yunion.io/x/pkg v1.10.1-0.20240826001854-ac73b70d75b7 h1:ceNLYp6CKYccbFw/ug9ohSa yunion.io/x/pkg v1.10.1-0.20240826001854-ac73b70d75b7/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM= 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.20240823033059-be6fe90dab22 h1:H+lxDpb8e2y2DwMRvo6Ujq3NK1zbR0gfVS9tdvjG4X0= -yunion.io/x/sqlchemy v1.1.3-0.20240823033059-be6fe90dab22/go.mod h1:5W8ghvJ4TNt/r2yDjjD3i4QsZgIiJX45dhRQBGWPHsQ= +yunion.io/x/sqlchemy v1.1.3-0.20240831153043-4030cea8d4b9 h1:vJSHj5jalKW7Vx5dqPmdI/jmpqMxR6nqHHtZSTQUZYM= +yunion.io/x/sqlchemy v1.1.3-0.20240831153043-4030cea8d4b9/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= diff --git a/vendor/modules.txt b/vendor/modules.txt index ecee93f80a..4838e499f8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1485,7 +1485,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.20240826095554-2919a9d956e4 +# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240827090500-d1bed3a44db5 ## explicit; go 1.18 yunion.io/x/cloudmux/pkg/apis yunion.io/x/cloudmux/pkg/apis/billing @@ -1635,7 +1635,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.20240823033059-be6fe90dab22 +# yunion.io/x/sqlchemy v1.1.3-0.20240831153043-4030cea8d4b9 ## explicit; go 1.17 yunion.io/x/sqlchemy yunion.io/x/sqlchemy/backends diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/huawei.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/huawei.go index b18fa48c26..ac5b190bd6 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/huawei.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/huawei.go @@ -227,6 +227,53 @@ func (self *SHuaweiClient) getAkClient() *akClient { } } +type sHuaweiError struct { + RequestId string `json:"request_id"` + ErrorMsg string `json:"error_msg"` + ErrorCode string `json:"error_code"` + Code string + Message string + ErrorInfo struct { + Message string + Code string + Title string + } `json:"error"` + Errorcode []string `json:"errorcode"` + ConvertMsg string + RawMsg jsonutils.JSONObject +} + +func (self *sHuaweiError) Error() string { + return jsonutils.Marshal(self).String() +} + +// https://support.huaweicloud.com/api-iam/iam_02_0006.html +var convertMsg = map[string]string{ + "1101": "用户名校验失败,请检查用户名", + "1103": "密码校验失败,请检查密码", + "1104": "手机号校验失败,请检查手机号", + "1108": "新密码不能与原密码相同,请修改新密码", + "1109": "用户名已存在,请修改用户名", + "1118": "密码是弱密码,重新选择密码", +} + +func (self *sHuaweiError) ParseErrorFromJsonResponse(statusCode int, status string, body jsonutils.JSONObject) error { + if body != nil { + body.Unmarshal(self) + // 特殊错误将返回原始错误信息 + if self.Error() == jsonutils.Marshal(sHuaweiError{}).String() { + self.RawMsg = body + } + } + for _, code := range self.Errorcode { + self.ConvertMsg = convertMsg[code] + } + if statusCode == 404 { + return errors.Wrapf(cloudprovider.ErrNotFound, self.Error()) + } + return self +} + func (self *SHuaweiClient) request(method httputils.THttpMethod, regionId, url string, query url.Values, params map[string]interface{}) (jsonutils.JSONObject, error) { client := self.getAkClient() if len(query) > 0 { @@ -252,11 +299,12 @@ func (self *SHuaweiClient) request(method httputils.THttpMethod, regionId, url s strings.Contains(url, "eps.myhuaweicloud.com")) && len(self.ownerId) > 0 { header.Set("X-Domain-Id", self.ownerId) } - _, resp, err := httputils.JSONRequest(client, context.Background(), method, url, header, body, self.debug) + req := httputils.NewJsonRequest(method, url, body) + req.SetHeader(header) + hwErr := &sHuaweiError{} + cli := httputils.NewJsonClient(client) + _, resp, err := cli.Send(context.Background(), req, hwErr, self.debug) if err != nil { - if e, ok := err.(*httputils.JSONClientError); ok && e.Code == 404 { - return nil, errors.Wrapf(cloudprovider.ErrNotFound, err.Error()) - } return nil, err } if gotypes.IsNil(resp) { @@ -471,7 +519,7 @@ func (self *SHuaweiClient) QueryAccountBalance() (*SBalance, error) { resp, err := self.list(service, "", "accounts/customer-accounts/balances", nil) if err != nil { // 国际区账号会报错: {"error_code":"CBC.0150","error_msg":"Access denied. The customer does not belong to the website you are now at."} - if e, ok := err.(*httputils.JSONClientError); ok && e.Class == "CBC.0150" { + if e, ok := err.(*sHuaweiError); ok && (e.ErrorCode == "CBC.0150" || e.ErrorCode == "CBC.0156") { continue } return nil, err diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/saml_provider.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/saml_provider.go index 2ff537d6c9..79e9fee60a 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/saml_provider.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/saml_provider.go @@ -21,7 +21,6 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" - "yunion.io/x/pkg/util/httputils" "yunion.io/x/pkg/util/samlutils" "yunion.io/x/pkg/util/stringutils" @@ -209,11 +208,11 @@ func (self *SHuaweiClient) CreateSAMLProvider(opts *cloudprovider.SAMLProviderCr if err == nil { return nil } - he, ok := errors.Cause(err).(*httputils.JSONClientError) + he, ok := errors.Cause(err).(*sHuaweiError) if !ok { return errors.Wrapf(err, "SAMLProviders.Update") } - if he.Code != 409 { + if he.ErrorInfo.Code != "409" { return errors.Wrapf(err, "SAMLProviders.Update") } samlName = fmt.Sprintf("%s-%d", string(name), idx) diff --git a/vendor/yunion.io/x/sqlchemy/ascii.go b/vendor/yunion.io/x/sqlchemy/ascii.go index 718de2fae6..f18d153f64 100644 --- a/vendor/yunion.io/x/sqlchemy/ascii.go +++ b/vendor/yunion.io/x/sqlchemy/ascii.go @@ -23,12 +23,42 @@ func (c *STableField) IsAscii() bool { return c.spec.IsAscii() } -func isFieldRequireAscii(f IQueryField) bool { +func (c *STableField) IsText() bool { + return c.spec.IsText() +} + +func (c *STableField) IsSearchable() bool { + return c.spec.IsSearchable() +} + +func getTableField(f IQueryField) *STableField { if gotypes.IsNil(f) { - return false + return nil } - if tableField, ok := f.(*STableField); ok { - return tableField.IsAscii() + switch tf := f.(type) { + case *STableField: + return tf + case *sQueryField: + return getTableField(tf.from.Field(f.Name())) + case *SSubQueryField: + return getTableField(tf.field) + default: + return nil + } +} + +func IsFieldText(f IQueryField) bool { + tf := getTableField(f) + if tf != nil { + return tf.IsText() && tf.IsSearchable() + } + return false +} + +func isFieldRequireAscii(f IQueryField) bool { + tf := getTableField(f) + if tf != nil { + return tf.IsAscii() } return false } diff --git a/vendor/yunion.io/x/sqlchemy/backends.go b/vendor/yunion.io/x/sqlchemy/backends.go index 6e2065663e..16253f3cde 100644 --- a/vendor/yunion.io/x/sqlchemy/backends.go +++ b/vendor/yunion.io/x/sqlchemy/backends.go @@ -155,6 +155,12 @@ type IBackend interface { UPPER(name string, field IQueryField) IQueryField // DATEDIFF DATEDIFF(unit string, field1, field2 IQueryField) IQueryField + + ///////////////////////////////////////////////////////////////////////////// + ///////////////////// Filters /////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// + + Equals(f IQueryField, v interface{}) ICondition } var _driver_tbl = make(map[DBBackendName]IBackend) diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/conditions.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/conditions.go new file mode 100644 index 0000000000..054f45985f --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/conditions.go @@ -0,0 +1,42 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dameng + +import ( + "yunion.io/x/log" + "yunion.io/x/sqlchemy" +) + +// SEqualsCondition represents equal operation between two fields +type SDamengEqualsCondition struct { + sqlchemy.STupleCondition +} + +// WhereClause implementation of SDamengEqualsCondition for ICondition +// 修复达梦数据库报错:数据类型不匹配 +func (t *SDamengEqualsCondition) WhereClause() string { + return sqlchemy.TupleConditionWhereClauseWithFuncname(&t.STupleCondition, "TEXT_EQUAL") +} + +// Equals filter conditions +func (dameng *SDamengBackend) Equals(f sqlchemy.IQueryField, v interface{}) sqlchemy.ICondition { + log.Debugf("field %s isFieldText: %v %#v", f.Name(), sqlchemy.IsFieldText(f), f) + if sqlchemy.IsFieldText(f) { + c := SDamengEqualsCondition{sqlchemy.NewTupleCondition(f, v)} + return &c + } else { + return dameng.SBaseBackend.Equals(f, v) + } +} diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/errors.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/errors.go deleted file mode 100644 index ac5356e2d3..0000000000 --- a/vendor/yunion.io/x/sqlchemy/backends/dameng/errors.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019 Yunion -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dameng - -import ( - "github.com/go-sql-driver/mysql" -) - -const ( - mysqlErrorTableNotExist = 0x47a -) - -func isMysqlError(err error, code uint16) bool { - if myErr, ok := err.(*mysql.MySQLError); ok { - return myErr.Number == code - } - return false -} diff --git a/vendor/yunion.io/x/sqlchemy/backends_base.go b/vendor/yunion.io/x/sqlchemy/backends_base.go index 92420c70e4..3855e21ad5 100644 --- a/vendor/yunion.io/x/sqlchemy/backends_base.go +++ b/vendor/yunion.io/x/sqlchemy/backends_base.go @@ -258,3 +258,8 @@ func (bb *SBaseBackend) QuoteChar() string { func (bb *SBaseBackend) PrepareInsertOrUpdateSQL(ts ITableSpec, insertColNames []string, insertFields []string, onPrimaryCols []string, updateSetCols []string, insertValues []interface{}, updateValues []interface{}) (string, []interface{}) { return "", nil } + +func (bb *SBaseBackend) Equals(f IQueryField, v interface{}) ICondition { + c := SEqualsCondition{NewTupleCondition(f, v)} + return &c +} diff --git a/vendor/yunion.io/x/sqlchemy/conditions.go b/vendor/yunion.io/x/sqlchemy/conditions.go index 31ec0d35fb..6860ccf5a1 100644 --- a/vendor/yunion.io/x/sqlchemy/conditions.go +++ b/vendor/yunion.io/x/sqlchemy/conditions.go @@ -369,15 +369,30 @@ type STupleCondition struct { } func tupleConditionWhereClause(t *STupleCondition, op string) string { + return tupleConditionWhereClauseInternal(t, op, "") +} + +func TupleConditionWhereClauseWithFuncname(t *STupleCondition, funcName string) string { + return tupleConditionWhereClauseInternal(t, ",", funcName) +} + +func tupleConditionWhereClauseInternal(t *STupleCondition, op string, funcName string) string { if isFieldRequireAscii(t.left) && !isVariableAscii(t.right) { return "0" } var buf bytes.Buffer + if len(funcName) > 0 { + buf.WriteString(funcName) + buf.WriteByte('(') + } buf.WriteString(t.left.Reference()) buf.WriteByte(' ') buf.WriteString(op) buf.WriteByte(' ') buf.WriteString(VarConditionWhereClause(t.right)) + if len(funcName) > 0 { + buf.WriteByte(')') + } return buf.String() } @@ -602,8 +617,7 @@ func (t *SEqualsCondition) WhereClause() string { // Equals method represents equal of two fields func Equals(f IQueryField, v interface{}) ICondition { - c := SEqualsCondition{NewTupleCondition(f, v)} - return &c + return f.database().backend.Equals(f, v) } // SNotEqualsCondition is the opposite of equal condition