From 94fcb7a4001a08e70f66885a9d16d721e66e2771 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Mon, 3 Dec 2018 07:14:43 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=9ASPolicyCredentia?= =?UTF-8?q?l=E5=AF=BC=E8=87=B4task=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/cloudcommon/policy/token.go | 122 +++++--------------------------- 1 file changed, 16 insertions(+), 106 deletions(-) diff --git a/pkg/cloudcommon/policy/token.go b/pkg/cloudcommon/policy/token.go index c42b846bf4..5cb7cfd55b 100644 --- a/pkg/cloudcommon/policy/token.go +++ b/pkg/cloudcommon/policy/token.go @@ -1,9 +1,8 @@ package policy import ( - "time" + "yunion.io/x/log" - "yunion.io/x/jsonutils" "yunion.io/x/pkg/gotypes" "yunion.io/x/onecloud/pkg/cloudcommon/consts" @@ -12,123 +11,34 @@ import ( ) type SPolicyTokenCredential struct { - Token mcclient.TokenCredential -} - -func (self *SPolicyTokenCredential) String() string { - return self.Token.String() -} - -func (self *SPolicyTokenCredential) IsZero() bool { - return self.Token.IsZero() -} - -func (self *SPolicyTokenCredential) GetProjectId() string { - return self.Token.GetProjectId() -} - -func (self *SPolicyTokenCredential) GetTenantId() string { - return self.Token.GetTenantId() -} - -func (self *SPolicyTokenCredential) GetUserId() string { - return self.Token.GetUserId() -} - -func (self *SPolicyTokenCredential) GetServiceURL(service, region, zone, endpointType string) (string, error) { - return self.Token.GetServiceURL(service, region, zone, endpointType) -} - -func (self *SPolicyTokenCredential) GetServiceURLs(service, region, zone, endpointType string) ([]string, error) { - return self.Token.GetServiceURLs(service, region, zone, endpointType) -} - -func (self *SPolicyTokenCredential) GetTokenString() string { - return self.Token.GetTokenString() -} - -func (self *SPolicyTokenCredential) GetDomainId() string { - return self.Token.GetDomainId() -} - -func (self *SPolicyTokenCredential) GetDomainName() string { - return self.Token.GetDomainName() -} - -func (self *SPolicyTokenCredential) GetTenantName() string { - return self.Token.GetTenantName() -} - -func (self *SPolicyTokenCredential) GetProjectName() string { - return self.Token.GetProjectName() -} - -func (self *SPolicyTokenCredential) GetUserName() string { - return self.Token.GetUserName() -} - -func (self *SPolicyTokenCredential) GetRoles() []string { - return self.Token.GetRoles() -} - -func (self *SPolicyTokenCredential) GetExpires() time.Time { - return self.Token.GetExpires() -} - -func (self *SPolicyTokenCredential) IsValid() bool { - return self.Token.IsValid() -} - -func (self *SPolicyTokenCredential) ValidDuration() time.Duration { - return self.Token.ValidDuration() -} - -func (self *SPolicyTokenCredential) GetRegions() []string { - return self.Token.GetRegions() -} - -func (self *SPolicyTokenCredential) GetServiceCatalog() mcclient.IServiceCatalog { - return self.Token.GetServiceCatalog() -} - -func (self *SPolicyTokenCredential) GetCatalogData(serviceTypes []string, region string) jsonutils.JSONObject { - return self.Token.GetCatalogData(serviceTypes, region) -} - -func (self *SPolicyTokenCredential) GetInternalServices(region string) []string { - return self.Token.GetInternalServices(region) -} - -func (self *SPolicyTokenCredential) GetExternalServices(region string) []mcclient.ExternalService { - return self.Token.GetExternalServices(region) -} - -func (self *SPolicyTokenCredential) GetEndpoints(region string, endpointType string) []mcclient.Endpoint { - return self.Token.GetEndpoints(region, endpointType) -} - -func (self *SPolicyTokenCredential) ToJson() jsonutils.JSONObject { - return self.Token.ToJson() + // usage embedded interface + mcclient.TokenCredential } func (self *SPolicyTokenCredential) HasSystemAdminPrivelege() bool { if consts.IsRbacEnabled() { - return PolicyManager.IsAdminCapable(self.Token) + return PolicyManager.IsAdminCapable(self.TokenCredential) } - return self.Token.HasSystemAdminPrivelege() + return self.TokenCredential.HasSystemAdminPrivelege() } func (self *SPolicyTokenCredential) IsAdminAllow(service string, resource string, action string, extra ...string) bool { if consts.IsRbacEnabled() { - result := PolicyManager.Allow(true, self.Token, service, resource, action, extra...) + result := PolicyManager.Allow(true, self.TokenCredential, service, resource, action, extra...) return result == rbacutils.AdminAllow } - return self.Token.IsAdminAllow(service, resource, action, extra...) + return self.TokenCredential.IsAdminAllow(service, resource, action, extra...) } func init() { - gotypes.RegisterSerializable(mcclient.TokenCredentialType, func() gotypes.ISerializable { - return &SPolicyTokenCredential{} + gotypes.RegisterSerializableTransformer(mcclient.TokenCredentialType, func(input gotypes.ISerializable) gotypes.ISerializable { + log.Debugf("do TokenCredential transform for %#v", input) + switch val := input.(type) { + case *mcclient.SSimpleToken: + return &SPolicyTokenCredential{val} + default: + return val + } }) } @@ -140,6 +50,6 @@ func FilterPolicyCredential(token mcclient.TokenCredential) mcclient.TokenCreden case *SPolicyTokenCredential: return token default: - return &SPolicyTokenCredential{Token: token} + return &SPolicyTokenCredential{TokenCredential: token} } } From 9ca04590c35e82070ef2d7636206ce985354119c Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Mon, 3 Dec 2018 13:17:14 +0800 Subject: [PATCH 2/2] update vendor --- Gopkg.lock | 14 +- .../go-windows-terminal-sequences/license | 9 - vendor/yunion.io/x/jsonutils/marshal.go | 256 ++++++++++++++---- vendor/yunion.io/x/jsonutils/reflect.go | 1 + vendor/yunion.io/x/pkg/gotypes/serialize.go | 39 ++- .../x/pkg/prettytable/prettytable.go | 14 +- .../yunion.io/x/pkg/util/secrules/secrules.go | 19 +- vendor/yunion.io/x/pkg/utils/profiler.go | 10 + vendor/yunion.io/x/structarg/structarg.go | 70 ++--- 9 files changed, 291 insertions(+), 141 deletions(-) delete mode 100644 vendor/github.com/konsorten/go-windows-terminal-sequences/license create mode 100644 vendor/yunion.io/x/pkg/utils/profiler.go diff --git a/Gopkg.lock b/Gopkg.lock index 454faee8ba..97e5f4c360 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1310,11 +1310,11 @@ [[projects]] branch = "master" - digest = "1:54554b3c72f4fcbd3c27c5137f9acd9d153d7e7150d77cd509af50c75fcb41b9" + digest = "1:a2346cf0c965791c281a428a3e9bf522913941028e4c814a774af7f3cc2360b0" name = "yunion.io/x/jsonutils" packages = ["."] pruneopts = "UT" - revision = "7079aada4c7e9a37e4c3b183bddb0ef684e038f2" + revision = "814e036849815935e5957ebd03bd0f4fc992fe83" [[projects]] branch = "master" @@ -1329,7 +1329,7 @@ [[projects]] branch = "master" - digest = "1:bf987f904fd821c6395fefdab956d070596eb401657fff40420014a3a8e3f45c" + digest = "1:5d9a659bf3c1d341cdf4135eca0009dbfa64a6728b3e0535c06afb6a76189a98" name = "yunion.io/x/pkg" packages = [ "gotypes", @@ -1353,7 +1353,6 @@ "util/secrules", "util/sets", "util/stringutils", - "util/sysutils", "util/timeutils", "util/trace", "util/ttlpool", @@ -1363,7 +1362,7 @@ "utils", ] pruneopts = "UT" - revision = "7614d751299a6703a05f757a13e6dc900332e31b" + revision = "cecf301871b09e94abaf1ff76d5ae7ac51ce0746" [[projects]] branch = "master" @@ -1375,11 +1374,11 @@ [[projects]] branch = "master" - digest = "1:f07a1ef9758f56186dd9039a8608bc9d537070a7c04479dbab6aeb42501001b7" + digest = "1:bbaf572e68e5dad4045e1e424af29838882c620df391fa1631dd8dc851c87a95" name = "yunion.io/x/structarg" packages = ["."] pruneopts = "UT" - revision = "e0cc2c73375327d401b100bd8988fa340c2687ee" + revision = "c95bf78846decd8dea379e925410f2895fb20076" [solve-meta] analyzer-name = "dep" @@ -1493,7 +1492,6 @@ "yunion.io/x/pkg/util/secrules", "yunion.io/x/pkg/util/sets", "yunion.io/x/pkg/util/stringutils", - "yunion.io/x/pkg/util/sysutils", "yunion.io/x/pkg/util/timeutils", "yunion.io/x/pkg/util/trace", "yunion.io/x/pkg/util/ttlpool", diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/license b/vendor/github.com/konsorten/go-windows-terminal-sequences/license deleted file mode 100644 index 14127cd831..0000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/license +++ /dev/null @@ -1,9 +0,0 @@ -(The MIT License) - -Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/yunion.io/x/jsonutils/marshal.go b/vendor/yunion.io/x/jsonutils/marshal.go index aff79cf1d2..97630bb987 100644 --- a/vendor/yunion.io/x/jsonutils/marshal.go +++ b/vendor/yunion.io/x/jsonutils/marshal.go @@ -12,37 +12,118 @@ import ( "reflect" "time" + "strings" "yunion.io/x/log" "yunion.io/x/pkg/gotypes" "yunion.io/x/pkg/tristate" - "yunion.io/x/pkg/util/reflectutils" "yunion.io/x/pkg/util/timeutils" + "yunion.io/x/pkg/utils" ) -func marshalSlice(val reflect.Value) *JSONArray { +func marshalSlice(val reflect.Value, info *jsonMarshalInfo) JSONObject { + if val.Len() == 0 && info != nil && info.omitEmpty { + return JSONNull + } objs := make([]JSONObject, val.Len()) for i := 0; i < val.Len(); i += 1 { - objs[i] = marshalValue(val.Index(i)) + objs[i] = marshalValue(val.Index(i), nil) + } + arr := NewArray(objs...) + if info != nil && info.forceString { + return NewString(arr.String()) + } else { + return arr } - return NewArray(objs...) } -func marshalMap(val reflect.Value) *JSONDict { +func marshalMap(val reflect.Value, info *jsonMarshalInfo) JSONObject { keys := val.MapKeys() + if len(keys) == 0 && info != nil && info.omitEmpty { + return JSONNull + } objPairs := make([]JSONPair, 0) for i := 0; i < len(keys); i += 1 { key := keys[i] - val := marshalValue(val.MapIndex(key)) + val := marshalValue(val.MapIndex(key), nil) if val != JSONNull { objPairs = append(objPairs, JSONPair{key: fmt.Sprintf("%s", key), val: val}) } } - return NewDict(objPairs...) + dict := NewDict(objPairs...) + if info != nil && info.forceString { + return NewString(dict.String()) + } else { + return dict + } } -func marshalStruct(val reflect.Value) *JSONDict { +func marshalStruct(val reflect.Value, info *jsonMarshalInfo) JSONObject { objPairs := struct2JSONPairs(val) - return NewDict(objPairs...) + if len(objPairs) == 0 && info != nil && info.omitEmpty { + return JSONNull + } + dict := NewDict(objPairs...) + if info != nil && info.forceString { + return NewString(dict.String()) + } else { + return dict + } +} + +type jsonMarshalInfo struct { + ignore bool + omitEmpty bool + omitFalse bool + omitZero bool + name string + forceString bool +} + +func parseJsonMarshalInfo(fieldTag reflect.StructTag) jsonMarshalInfo { + info := jsonMarshalInfo{} + info.omitEmpty = true + info.omitZero = false + info.omitFalse = false + + tags := utils.TagMap(fieldTag) + if val, ok := tags["json"]; ok { + keys := strings.Split(val, ",") + if len(keys) > 0 { + if keys[0] == "-" { + if len(keys) > 1 { + info.name = keys[0] + } else { + info.ignore = true + } + } else { + info.name = keys[0] + } + } + if len(keys) > 1 { + for _, k := range keys[1:] { + switch k { + case "omitempty": + info.omitEmpty = true + case "allowempty": + info.omitEmpty = false + case "omitzero": + info.omitZero = true + case "allowzero": + info.omitZero = false + case "omitfalse": + info.omitFalse = true + case "allowfalse": + info.omitFalse = false + case "string": + info.forceString = true + } + } + } + } + if val, ok := tags["name"]; ok { + info.name = val + } + return info } func struct2JSONPairs(val reflect.Value) []JSONPair { @@ -53,16 +134,44 @@ func struct2JSONPairs(val reflect.Value) []JSONPair { if !gotypes.IsFieldExportable(fieldType.Name) { // unexportable field, ignore continue } - if fieldType.Type.Kind() == reflect.Struct && fieldType.Anonymous { // embbed struct - newPairs := struct2JSONPairs(val.Field(i)) - objPairs = append(objPairs, newPairs...) - } else { - key := reflectutils.GetStructFieldName(&fieldType) // utils.CamelSplit(fieldType.Name, "_") - if key == "" { + if fieldType.Anonymous { + nextVal := val.Field(i) + switch fieldType.Type.Kind() { + case reflect.Struct: // embbed struct + nextVal = val.Field(i) + case reflect.Interface: // embbed interface + CHECKINTERFACE: + for { + switch nextVal.Type().Kind() { + case reflect.Interface: + nextVal = nextVal.Elem() + case reflect.Ptr: + nextVal = reflect.Indirect(nextVal) + case reflect.Struct: + break CHECKINTERFACE + default: + log.Warningf("embeded interface point to a non struct data %s", nextVal.Type()) + break CHECKINTERFACE + } + } + default: + log.Warningf("unsupport anonymous embeded type %s", fieldType.Type.Name()) continue } - val := marshalValue(val.Field(i)) - if val != JSONNull { + newPairs := struct2JSONPairs(nextVal) + objPairs = append(objPairs, newPairs...) + } else { + jsonInfo := parseJsonMarshalInfo(fieldType.Tag) + + if jsonInfo.ignore { + continue + } + key := jsonInfo.name + if len(key) == 0 { + key = utils.CamelSplit(fieldType.Name, "_") + } + val := marshalValue(val.Field(i), &jsonInfo) + if val != nil && val != JSONNull { objPair := JSONPair{key: key, val: val} objPairs = append(objPairs, objPair) } @@ -71,23 +180,41 @@ func struct2JSONPairs(val reflect.Value) []JSONPair { return objPairs } -func marshalInt64(val int64) *JSONInt { - return NewInt(val) -} - -func marshalFloat64(val float64) *JSONFloat { - return NewFloat(val) -} - -func marshalBoolean(val bool) *JSONBool { - if val { - return JSONTrue +func marshalInt64(val int64, info *jsonMarshalInfo) JSONObject { + if val == 0 && info != nil && info.omitZero { + return JSONNull + } else if info != nil && info.forceString { + return NewString(fmt.Sprintf("%d", val)) } else { - return JSONFalse + return NewInt(val) } } -func marshalTristate(val tristate.TriState) JSONObject { +func marshalFloat64(val float64, info *jsonMarshalInfo) JSONObject { + if val == 0.0 && info != nil && info.omitZero { + return JSONNull + } else if info != nil && info.forceString { + return NewString(fmt.Sprintf("%f", val)) + } else { + return NewFloat(val) + } +} + +func marshalBoolean(val bool, info *jsonMarshalInfo) JSONObject { + if !val && info != nil && info.omitFalse { + return JSONNull + } else if info != nil && info.forceString { + return NewString(fmt.Sprintf("%v", val)) + } else { + if val { + return JSONTrue + } else { + return JSONFalse + } + } +} + +func marshalTristate(val tristate.TriState, info *jsonMarshalInfo) JSONObject { if val.IsTrue() { return JSONTrue } else if val.IsFalse() { @@ -97,16 +224,19 @@ func marshalTristate(val tristate.TriState) JSONObject { } } -func marshalString(val string) JSONObject { - if len(val) == 0 { +func marshalString(val string, info *jsonMarshalInfo) JSONObject { + if len(val) == 0 && info != nil && info.omitEmpty { return JSONNull } else { return NewString(val) } } -func marshalTime(val time.Time) *JSONString { +func marshalTime(val time.Time, info *jsonMarshalInfo) JSONObject { if val.IsZero() { + if info != nil && info.omitEmpty { + return JSONNull + } return NewString("") } else { return NewString(timeutils.FullIsoTime(val)) @@ -118,10 +248,10 @@ func Marshal(obj interface{}) JSONObject { return JSONNull } objValue := reflect.Indirect(reflect.ValueOf(obj)) - return marshalValue(objValue) + return marshalValue(objValue, nil) } -func marshalValue(objValue reflect.Value) JSONObject { +func marshalValue(objValue reflect.Value, info *jsonMarshalInfo) JSONObject { switch objValue.Type() { case JSONDictPtrType, JSONArrayPtrType, JSONBoolPtrType, JSONIntPtrType, JSONFloatPtrType, JSONStringPtrType, JSONObjectType: if objValue.IsNil() { @@ -131,81 +261,105 @@ func marshalValue(objValue reflect.Value) JSONObject { case JSONDictType: json, ok := objValue.Interface().(JSONDict) if ok { - return &json + if len(json.data) == 0 && info != nil && info.omitEmpty { + return JSONNull + } else { + return &json + } } else { return JSONNull } case JSONArrayType: json, ok := objValue.Interface().(JSONArray) if ok { - return &json + if len(json.data) == 0 && info != nil && info.omitEmpty { + return JSONNull + } else { + return &json + } } else { return JSONNull } case JSONBoolType: json, ok := objValue.Interface().(JSONBool) if ok { - return &json + if !json.data && info != nil && info.omitEmpty { + return JSONNull + } else { + return &json + } } else { return JSONNull } case JSONIntType: json, ok := objValue.Interface().(JSONInt) if ok { - return &json + if json.data == 0 && info != nil && info.omitEmpty { + return JSONNull + } else { + return &json + } } else { return JSONNull } case JSONFloatType: json, ok := objValue.Interface().(JSONFloat) if ok { - return &json + if json.data == 0.0 && info != nil && info.omitEmpty { + return JSONNull + } else { + return &json + } } else { return JSONNull } case JSONStringType: json, ok := objValue.Interface().(JSONString) if ok { - return &json + if len(json.data) == 0 && info != nil && info.omitEmpty { + return JSONNull + } else { + return &json + } } else { return JSONNull } case tristate.TriStateType: tri, ok := objValue.Interface().(tristate.TriState) if ok { - return marshalTristate(tri) + return marshalTristate(tri, info) } else { return JSONNull } } switch objValue.Kind() { case reflect.Slice, reflect.Array: - return marshalSlice(objValue) + return marshalSlice(objValue, info) case reflect.Struct: if objValue.Type() == gotypes.TimeType { - return marshalTime(objValue.Interface().(time.Time)) + return marshalTime(objValue.Interface().(time.Time), info) } else { - return marshalStruct(objValue) + return marshalStruct(objValue, info) } case reflect.Map: - return marshalMap(objValue) + return marshalMap(objValue, info) case reflect.String: strValue := objValue.Convert(gotypes.StringType) - return marshalString(strValue.Interface().(string)) + return marshalString(strValue.Interface().(string), info) case reflect.Bool: - return marshalBoolean(objValue.Interface().(bool)) + return marshalBoolean(objValue.Interface().(bool), info) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: intValue := objValue.Convert(gotypes.Int64Type) - return marshalInt64(intValue.Interface().(int64)) + return marshalInt64(intValue.Interface().(int64), info) case reflect.Float32, reflect.Float64: floatValue := objValue.Convert(gotypes.Float64Type) - return marshalFloat64(floatValue.Interface().(float64)) + return marshalFloat64(floatValue.Interface().(float64), info) case reflect.Interface, reflect.Ptr: if objValue.IsNil() { return JSONNull } - return marshalValue(objValue.Elem()) + return marshalValue(objValue.Elem(), info) default: log.Errorf("unsupport object %s %s", objValue.Type(), objValue.Interface()) return JSONNull diff --git a/vendor/yunion.io/x/jsonutils/reflect.go b/vendor/yunion.io/x/jsonutils/reflect.go index d19df92fae..eab866e8dc 100644 --- a/vendor/yunion.io/x/jsonutils/reflect.go +++ b/vendor/yunion.io/x/jsonutils/reflect.go @@ -66,5 +66,6 @@ func JSONDeserialize(objType reflect.Type, strVal string) (gotypes.ISerializable if err != nil { return nil, err } + objPtr = gotypes.Transform(objType, objPtr) return objPtr, nil } diff --git a/vendor/yunion.io/x/pkg/gotypes/serialize.go b/vendor/yunion.io/x/pkg/gotypes/serialize.go index fdbc271497..ae601e6310 100644 --- a/vendor/yunion.io/x/pkg/gotypes/serialize.go +++ b/vendor/yunion.io/x/pkg/gotypes/serialize.go @@ -14,10 +14,13 @@ type ISerializable interface { type FuncSerializableAllocator func() ISerializable +type FuncSerializableTransformer func(ISerializable) ISerializable + var ( - ISerializableType = reflect.TypeOf((*ISerializable)(nil)).Elem() - serializableAllocators = map[reflect.Type]FuncSerializableAllocator{} - ErrTypeNotSerializable = errors.New("Type not serializable") + ISerializableType = reflect.TypeOf((*ISerializable)(nil)).Elem() + serializableAllocators = map[reflect.Type]FuncSerializableAllocator{} + serializableTransformers = map[reflect.Type][]FuncSerializableTransformer{} + ErrTypeNotSerializable = errors.New("Type not serializable") ) // RegisterSerializable registers an allocator func for the specified serializable type. @@ -29,17 +32,41 @@ func RegisterSerializable(valType reflect.Type, alloc FuncSerializableAllocator) if !IsSerializable(valType) { panic(valType.String() + " does not implement ISerializable") } + if _, ok := serializableAllocators[valType]; ok { + panic(valType.String() + " has been registered, might need to register a transformer") + } serializableAllocators[valType] = alloc } +func RegisterSerializableTransformer(valType reflect.Type, trans FuncSerializableTransformer) { + if !IsSerializable(valType) { + panic(valType.String() + " does not implement ISerializable") + } + if _, ok := serializableTransformers[valType]; !ok { + serializableTransformers[valType] = make([]FuncSerializableTransformer, 0) + } + serializableTransformers[valType] = append(serializableTransformers[valType], trans) +} + func IsSerializable(valType reflect.Type) bool { return valType.Implements(ISerializableType) } func NewSerializable(objType reflect.Type) (ISerializable, error) { deserFunc, ok := serializableAllocators[objType] - if ok { - return deserFunc(), nil + if !ok { + return nil, ErrTypeNotSerializable } - return nil, ErrTypeNotSerializable + retVal := deserFunc() + return retVal, nil +} + +func Transform(objType reflect.Type, retVal ISerializable) ISerializable { + transFuncs, ok := serializableTransformers[objType] + if ok { + for i := 0; i < len(transFuncs); i += 1 { + retVal = transFuncs[i](retVal) + } + } + return retVal } diff --git a/vendor/yunion.io/x/pkg/prettytable/prettytable.go b/vendor/yunion.io/x/pkg/prettytable/prettytable.go index f5ee4f34f1..feba929161 100644 --- a/vendor/yunion.io/x/pkg/prettytable/prettytable.go +++ b/vendor/yunion.io/x/pkg/prettytable/prettytable.go @@ -3,6 +3,7 @@ package prettytable import ( "bytes" "strings" + "unicode" ) type AlignmentType uint8 @@ -102,6 +103,17 @@ func textLine(buf *bytes.Buffer, columns []ptColumn, widths []int) { } } +func runeDisplayWidth(r rune) int { + const puncts = "。,;:()、?《》" + if unicode.Is(unicode.Han, r) { + return 2 + } + if strings.ContainsRune(puncts, r) { + return 2 + } + return 1 +} + // cellDisplayWidth returns display width of the cell when printed as the // nthCol. prevWidth is the total display width (as return by this same func) // of previous cells in the same line @@ -116,7 +128,7 @@ func cellDisplayWidth(cell string, nthCol int, prevWidth int) int { for _, c := range line { incr := 0 if c != '\t' { - incr = 1 + incr = runeDisplayWidth(c) } else { // terminal with have the char TabWidth aligned incr = TabWidth - (x & (TabWidth - 1)) diff --git a/vendor/yunion.io/x/pkg/util/secrules/secrules.go b/vendor/yunion.io/x/pkg/util/secrules/secrules.go index 037bb62d45..6437ff1ae9 100644 --- a/vendor/yunion.io/x/pkg/util/secrules/secrules.go +++ b/vendor/yunion.io/x/pkg/util/secrules/secrules.go @@ -127,21 +127,12 @@ func ParseSecurityRule(pattern string) (*SecurityRule, error) { return nil, ErrInvalidAction } } else if status == SEG_IP { - // NOTE regutils.MatchCIDR actually also matches IP address without prefix length if regutils.MatchCIDR(seg) { - if idx := strings.Index(seg, "/"); idx > -1 { - if _, ipnet, err := net.ParseCIDR(seg); err != nil { - return nil, ErrInvalidNet - } else { - rule.IPNet = ipnet - } - } else if ip := net.ParseIP(seg); ip != nil { - rule.IPNet = &net.IPNet{ - IP: ip, - Mask: net.CIDRMask(32, 32), - } - } else { - return nil, ErrInvalidIPAddr + _, rule.IPNet, _ = net.ParseCIDR(seg) + } else if regutils.MatchIPAddr(seg) { + rule.IPNet = &net.IPNet{ + IP: net.ParseIP(seg), + Mask: net.CIDRMask(32, 32), } } else { rule.IPNet = &net.IPNet{ diff --git a/vendor/yunion.io/x/pkg/utils/profiler.go b/vendor/yunion.io/x/pkg/utils/profiler.go new file mode 100644 index 0000000000..35064e43c5 --- /dev/null +++ b/vendor/yunion.io/x/pkg/utils/profiler.go @@ -0,0 +1,10 @@ +package utils + +import ( + "io" + "runtime/pprof" +) + +func DumpAllGoroutineStack(w io.Writer) { + pprof.Lookup("goroutine").WriteTo(w, 1) +} diff --git a/vendor/yunion.io/x/structarg/structarg.go b/vendor/yunion.io/x/structarg/structarg.go index e09e97cdad..ff749484c7 100644 --- a/vendor/yunion.io/x/structarg/structarg.go +++ b/vendor/yunion.io/x/structarg/structarg.go @@ -187,56 +187,6 @@ func (this *ArgumentParser) addStructArgument(tp reflect.Type, val reflect.Value return nil } -/*func findWord(str []byte, offset int) (string, int) { - var buffer bytes.Buffer - i := skipEmpty(str, offset) - if i >= len(str) { - return "", i - } - var endstr string - quote := false - if str[i] == '"' { - quote = true - endstr = "\"" - i++ - } else if str[i] == '\'' { - quote = true - endstr = "'" - i++ - } else { - endstr = " :,\t\n}]" - } - for i < len(str) { - if quote && str[i] == '\\' { - if i+1 < len(str) { - i++ - switch str[i] { - case 'n': - buffer.WriteByte('\n') - case 'r': - buffer.WriteByte('\r') - case 't': - buffer.WriteByte('\t') - default: - buffer.WriteByte(str[i]) - } - i++ - } else { - break - } - } else if strings.IndexByte(endstr, str[i]) >= 0 { // end - if quote { - i++ - } - break - } else { - buffer.WriteByte(str[i]) - i++ - } - } - return buffer.String(), i -}*/ - func (this *ArgumentParser) addArgument(f reflect.StructField, v reflect.Value) error { tagMap := utils.TagMap(f.Tag) help := tagMap[TAG_HELP] @@ -901,6 +851,14 @@ func (this *ArgumentParser) ParseArgs(args []string, ignore_unknown bool) error return err } +func isQuotedByChar(str string, quoteChar byte) bool { + return str[0] == quoteChar && str[len(str)-1] == quoteChar +} + +func isQuoted(str string) bool { + return isQuotedByChar(str, '"') || isQuotedByChar(str, '\'') +} + func (this *ArgumentParser) parseKeyValue(key, value string) error { arg := this.findOptionalArgument(key) if arg != nil { @@ -914,7 +872,15 @@ func (this *ArgumentParser) parseKeyValue(key, value string) error { } } } else { - return arg.SetValue(value) + if !isQuoted(value) { + value = fmt.Sprintf("\"%s\"", value) + } + values := utils.FindWords([]byte(value), 0) + if len(values) == 1 { + return arg.SetValue(values[0]) + } else { + log.Warningf("too many arguments %#v for %s", values, key) + } } } else { log.Warningf("Cannot find argument %s", key) @@ -964,7 +930,7 @@ func (this *ArgumentParser) ParseFile(filepath string) error { for scanner.Scan() { line := scanner.Text() line = strings.TrimSpace(removeComments(line)) - line = removeCharacters(line, `"'`) + // line = removeCharacters(line, `"'`) if len(line) > 0 { key, val, e := line2KeyValue(line) if e == nil {