From d097679e472f0fc2f69a04d99e304178b49cf3fd Mon Sep 17 00:00:00 2001 From: TangBin Date: Tue, 22 Dec 2020 18:05:22 +0800 Subject: [PATCH] fix(region): cloudregion&zone add namei18n --- pkg/cloudcommon/db/i18n.go | 291 ++++++++++++++++++ pkg/cloudprovider/i18n.go | 39 +++ pkg/cloudprovider/resources.go | 6 + pkg/compute/models/cloudregionresource.go | 2 +- pkg/compute/models/cloudregions.go | 27 +- pkg/compute/models/i18nresource.go | 64 ++++ pkg/compute/models/skus.go | 1 + pkg/compute/models/zones.go | 25 +- pkg/compute/service/handlers.go | 1 + .../guestman/forwarder/api/forwarder.pb.go | 5 +- .../forwarder/api/forwarder_grpc.pb.go | 1 + pkg/i18n/table.go | 17 + pkg/multicloud/aliyun/aliyun.go | 1 + pkg/multicloud/aliyun/region.go | 7 + pkg/multicloud/aliyun/zone.go | 6 + pkg/multicloud/apsara/apsara.go | 1 + pkg/multicloud/apsara/region.go | 7 + pkg/multicloud/apsara/zone.go | 7 + pkg/multicloud/aws/aws.go | 1 + pkg/multicloud/aws/region.go | 40 +++ pkg/multicloud/aws/zone.go | 7 + pkg/multicloud/azure/azure.go | 1 + pkg/multicloud/azure/region.go | 7 + pkg/multicloud/azure/zone.go | 4 + pkg/multicloud/ctyun/ctyun.go | 1 + pkg/multicloud/ctyun/region.go | 7 + pkg/multicloud/ctyun/zone.go | 6 + pkg/multicloud/esxi/manager.go | 6 + pkg/multicloud/google/region.go | 7 + pkg/multicloud/google/zone.go | 6 + pkg/multicloud/huawei/huawei.go | 1 + pkg/multicloud/huawei/region.go | 7 + pkg/multicloud/huawei/zone.go | 7 + pkg/multicloud/objectstore/objectstore.go | 6 + pkg/multicloud/openstack/region.go | 6 + pkg/multicloud/openstack/zone.go | 6 + pkg/multicloud/qcloud/qcloud.go | 1 + pkg/multicloud/qcloud/region.go | 7 + pkg/multicloud/qcloud/zone.go | 7 + pkg/multicloud/ucloud/consts.go | 57 ++++ pkg/multicloud/ucloud/region.go | 13 + pkg/multicloud/ucloud/zone.go | 13 + pkg/multicloud/zstack/region.go | 6 + pkg/multicloud/zstack/zone.go | 6 + 44 files changed, 737 insertions(+), 7 deletions(-) create mode 100644 pkg/cloudcommon/db/i18n.go create mode 100644 pkg/cloudprovider/i18n.go create mode 100644 pkg/compute/models/i18nresource.go diff --git a/pkg/cloudcommon/db/i18n.go b/pkg/cloudcommon/db/i18n.go new file mode 100644 index 0000000000..c96b93df65 --- /dev/null +++ b/pkg/cloudcommon/db/i18n.go @@ -0,0 +1,291 @@ +package db + +import ( + "context" + + "github.com/pkg/errors" + "golang.org/x/text/language" + + "yunion.io/x/log" + "yunion.io/x/pkg/util/compare" + + "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" + "yunion.io/x/onecloud/pkg/i18n" + "yunion.io/x/onecloud/pkg/mcclient" +) + +type IModelI18nBase interface { + GetKeyValue() string + Lookup(tag i18n.Tag) string +} + +type IModelI18nEntry interface { + IModelI18nBase + GetGlobalId() string + GetObjType() string + GetObjId() string + GetKeyName() string +} + +type IModelI18nTable interface { + GetI18nEntries() map[string]IModelI18nEntry +} + +type SModelI18nEntry struct { + model IModel + i18nEntry IModelI18nBase + modelKeyName string +} + +func NewSModelI18nEntry(keyName string, model IModel, i18nEntry IModelI18nBase) *SModelI18nEntry { + return &SModelI18nEntry{model: model, modelKeyName: keyName, i18nEntry: i18nEntry} +} + +func (self *SModelI18nEntry) GetObjType() string { + return self.model.Keyword() +} + +func (self *SModelI18nEntry) GetObjId() string { + return self.model.GetId() +} + +func (self *SModelI18nEntry) GetKeyName() string { + return self.modelKeyName +} + +func (self *SModelI18nEntry) GetKeyValue() string { + return self.i18nEntry.GetKeyValue() +} + +func (self *SModelI18nEntry) Lookup(tag i18n.Tag) string { + return self.i18nEntry.Lookup(tag) +} + +func (self *SModelI18nEntry) GetGlobalId() string { + return self.model.Keyword() + "::" + self.model.GetId() + "::" + self.modelKeyName +} + +type SModelI18nTable struct { + i18nEntires []IModelI18nEntry +} + +func NewSModelI18nTable(i18nEntires []IModelI18nEntry) *SModelI18nTable { + return &SModelI18nTable{i18nEntires: i18nEntires} +} + +func (t *SModelI18nTable) GetI18nEntries() map[string]IModelI18nEntry { + ret := make(map[string]IModelI18nEntry, 0) + for i := range t.i18nEntires { + entry := t.i18nEntires[i] + ret[entry.GetKeyValue()] = entry + } + + return ret +} + +type SI18nManager struct { + SStandaloneAnonResourceBaseManager +} + +type SI18n struct { + SStandaloneAnonResourceBase + + // 资源类型 + // example: network + ObjType string `width:"40" charset:"ascii" index:"true" list:"user" get:"user"` + + // 资源ID + // example: 87321a70-1ecb-422a-8b0c-c9aa632a46a7 + ObjId string `width:"88" charset:"ascii" index:"true" list:"user" get:"user"` + + // 资源KEY + // exmaple: name + KeyName string `width:"64" charset:"utf8" primary:"true" list:"user" get:"user"` + + // 资源原始值 + // example: 技术部 + KeyValue string `charset:"utf8" list:"user" get:"user"` + + // KeyValue 对应中文翻译 + Cn string `charset:"utf8" list:"user" get:"user" update:"admin_required" update:"admin"` + + // KeyValue 对应英文翻译 + En string `charset:"utf8" list:"user" get:"user" update:"admin_required" update:"admin"` +} + +var I18nManager *SI18nManager + +func init() { + I18nManager = &SI18nManager{ + SStandaloneAnonResourceBaseManager: NewStandaloneAnonResourceBaseManager( + SI18n{}, + "i18n_tbl", + "i18n", + "i18ns", + ), + } + I18nManager.SetVirtualObject(I18nManager) +} + +var tableLangSupported = []language.Tag{ + language.English, + language.Chinese, +} +var tableLangMatcher = language.NewMatcher(tableLangSupported) + +func tableLangMatch(tag language.Tag) language.Tag { + _, i, _ := tableLangMatcher.Match(tag) + return tableLangSupported[i] +} + +func (manager *SModelBaseManager) GetModelI18N(ctx context.Context, model IModel) ([]SI18n, error) { + ret := []SI18n{} + q := manager.Query().Equals("obj_type", model.Keyword()).Equals("obj_id", model.GetId()) + err := FetchModelObjects(manager, q, &ret) + if err != nil { + return nil, errors.Wrap(err, "FetchModelObjects") + } + + return ret, err +} + +func (manager *SI18nManager) getExternalI18nItems(ctx context.Context, table IModelI18nTable) []IModelI18nEntry { + ret := make([]IModelI18nEntry, 0) + items := table.GetI18nEntries() + for k, _ := range items { + ret = append(ret, items[k]) + } + + return ret +} + +func (manager *SI18nManager) RemoveI18ns(ctx context.Context, userCred mcclient.TokenCredential, model IModel) error { + dbItems := []SI18n{} + err := manager.Query().Equals("obj_type", model.Keyword()).Equals("obj_id", model.GetId()).All(&dbItems) + if err != nil { + return err + } + + for i := 0; i < len(dbItems); i += 1 { + err = dbItems[i].removeI18n(ctx, userCred) + if err != nil { + return err + } + } + + return nil +} + +func (manager *SI18nManager) SyncI18ns(ctx context.Context, userCred mcclient.TokenCredential, model IModel, table IModelI18nTable) ([]SI18n, []IModelI18nEntry, compare.SyncResult) { + lockman.LockClass(ctx, manager, "") + defer lockman.ReleaseClass(ctx, manager, "") + syncResult := compare.SyncResult{} + + extItems := manager.getExternalI18nItems(ctx, table) + dbItems := make([]SI18n, 0) + q := manager.Query().Equals("obj_type", model.Keyword()).Equals("obj_id", model.GetId()) + err := FetchModelObjects(manager, q, &dbItems) + if err != nil { + syncResult.Error(err) + return nil, nil, syncResult + } + + removed := make([]SI18n, 0) + commondb := make([]SI18n, 0) + commonext := make([]IModelI18nEntry, 0) + added := make([]IModelI18nEntry, 0) + + err = compare.CompareSets(dbItems, extItems, &removed, &commondb, &commonext, &added) + if err != nil { + syncResult.Error(err) + return nil, nil, syncResult + } + + for i := 0; i < len(removed); i += 1 { + err = removed[i].removeI18n(ctx, userCred) + if err != nil { + syncResult.DeleteError(err) + } else { + syncResult.Delete() + } + } + + locals := make([]SI18n, 0) + remotes := make([]IModelI18nEntry, 0) + for i := 0; i < len(commondb); i += 1 { + err = commondb[i].updateFromI18n(ctx, userCred, commonext[i]) + if err != nil { + syncResult.UpdateError(err) + } else { + locals = append(locals, commondb[i]) + remotes = append(remotes, commonext[i]) + syncResult.Update() + } + } + for i := 0; i < len(added); i += 1 { + new, err := manager.newFromI18n(ctx, userCred, added[i]) + if err != nil { + syncResult.AddError(err) + } else { + locals = append(locals, *new) + remotes = append(remotes, added[i]) + syncResult.Add() + } + } + + return locals, remotes, syncResult +} + +func (manager *SI18nManager) newFromI18n(ctx context.Context, userCred mcclient.TokenCredential, entry IModelI18nEntry) (*SI18n, error) { + in := SI18n{} + in.SetModelManager(manager, &in) + + in.ObjId = entry.GetObjId() + in.ObjType = entry.GetObjType() + in.KeyName = entry.GetKeyName() + in.KeyValue = entry.GetKeyValue() + in.Cn = entry.Lookup(i18n.I18N_TAG_CHINESE) + in.En = entry.Lookup(i18n.I18N_TAG_ENGLISH) + + err := manager.TableSpec().Insert(ctx, &in) + if err != nil { + log.Infof("newFromI18n fail %s", err) + return nil, err + } + + return &in, nil +} + +func (self *SI18n) updateFromI18n(ctx context.Context, userCred mcclient.TokenCredential, entry IModelI18nEntry) error { + _, err := UpdateWithLock(ctx, self, func() error { + self.KeyValue = entry.GetKeyValue() + self.Cn = entry.Lookup(i18n.I18N_TAG_CHINESE) + self.En = entry.Lookup(i18n.I18N_TAG_ENGLISH) + + return nil + }) + if err != nil { + log.Infof("updateFromI18n error %s", err) + return err + } + + return nil +} + +func (self *SI18n) removeI18n(ctx context.Context, userCred mcclient.TokenCredential) error { + lockman.LockObject(ctx, self) + defer lockman.ReleaseObject(ctx, self) + + err := self.Delete(ctx, userCred) + return err +} + +func (self SI18n) GetExternalId() string { + return self.ObjType + "::" + self.ObjId + "::" + self.KeyName +} + +func (self *SI18n) Lookup(ctx context.Context) string { + entry := i18n.NewTableEntry().CN(self.Cn).EN(self.En) + v, _ := entry.Lookup(ctx) + return v +} diff --git a/pkg/cloudprovider/i18n.go b/pkg/cloudprovider/i18n.go new file mode 100644 index 0000000000..15b4ca781e --- /dev/null +++ b/pkg/cloudprovider/i18n.go @@ -0,0 +1,39 @@ +package cloudprovider + +import ( + "yunion.io/x/onecloud/pkg/i18n" +) + +type SModelI18nEntry struct { + Value string + valueI18n map[i18n.Tag]string +} + +func NewSModelI18nEntry(value string) *SModelI18nEntry { + vn := make(map[i18n.Tag]string, 0) + return &SModelI18nEntry{Value: value, valueI18n: vn} +} + +func (self *SModelI18nEntry) GetKeyValue() string { + return self.Value +} + +func (self *SModelI18nEntry) Lookup(tag i18n.Tag) string { + if v, ok := self.valueI18n[tag]; ok { + return v + } + + return self.Value +} + +func (self *SModelI18nEntry) CN(v string) *SModelI18nEntry { + self.valueI18n[i18n.I18N_TAG_CHINESE] = v + return self +} + +func (self *SModelI18nEntry) EN(v string) *SModelI18nEntry { + self.valueI18n[i18n.I18N_TAG_ENGLISH] = v + return self +} + +type SModelI18nTable map[string]*SModelI18nEntry diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 10d748e184..48a77829c9 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -59,8 +59,13 @@ type IBillingResource interface { IsAutoRenew() bool } +type ICloudI18nResource interface { + GetI18n() SModelI18nTable +} + type ICloudRegion interface { ICloudResource + ICloudI18nResource // GetLatitude() float32 // GetLongitude() float32 @@ -152,6 +157,7 @@ type ICloudRegion interface { type ICloudZone interface { ICloudResource + ICloudI18nResource GetIRegion() ICloudRegion diff --git a/pkg/compute/models/cloudregionresource.go b/pkg/compute/models/cloudregionresource.go index e36d6a98ce..f4c6630ab0 100644 --- a/pkg/compute/models/cloudregionresource.go +++ b/pkg/compute/models/cloudregionresource.go @@ -96,7 +96,7 @@ func (manager *SCloudregionResourceBaseManager) FetchCustomizeColumns( } for i := range rows { if region, ok := regions[regionIds[i]]; ok { - rows[i] = region.GetRegionInfo() + rows[i] = region.GetRegionInfo(ctx) } else { rows[i] = api.CloudregionResourceInfo{} } diff --git a/pkg/compute/models/cloudregions.go b/pkg/compute/models/cloudregions.go index 242070887c..01533ac520 100644 --- a/pkg/compute/models/cloudregions.go +++ b/pkg/compute/models/cloudregions.go @@ -41,6 +41,7 @@ import ( type SCloudregionManager struct { db.SEnabledStatusStandaloneResourceBaseManager db.SExternalizedResourceBaseManager + SI18nResourceBaseManager } var CloudregionManager *SCloudregionManager @@ -59,6 +60,7 @@ func init() { type SCloudregion struct { db.SEnabledStatusStandaloneResourceBase + SI18nResourceBase SManagedResourceBase db.SExternalizedResourceBase @@ -445,12 +447,17 @@ func (self *SCloudregion) syncRemoveCloudRegion(ctx context.Context, userCred mc lockman.LockObject(ctx, self) defer lockman.ReleaseObject(ctx, self) + err := self.RemoveI18ns(ctx, userCred, self) + if err != nil { + return err + } + // err := self.ValidateDeleteCondition(ctx) // if err == nil { // err = self.Delete(ctx, userCred) // } - err := self.SetStatus(userCred, api.CLOUD_REGION_STATUS_OUTOFSERVICE, "Out of sync") + err = self.SetStatus(userCred, api.CLOUD_REGION_STATUS_OUTOFSERVICE, "Out of sync") if err == nil { _, err = self.PerformDisable(ctx, userCred, nil, apis.PerformDisableInput{}) } @@ -467,6 +474,11 @@ func (self *SCloudregion) syncRemoveCloudRegion(ctx context.Context, userCred mc } func (self *SCloudregion) syncWithCloudRegion(ctx context.Context, userCred mcclient.TokenCredential, cloudRegion cloudprovider.ICloudRegion, provider *SCloudprovider) error { + err := CloudregionManager.SyncI18ns(ctx, userCred, self, cloudRegion.GetI18n()) + if err != nil { + return errors.Wrap(err, "SyncI18ns") + } + factory, err := provider.GetProviderFactory() if err != nil { return err @@ -529,6 +541,12 @@ func (manager *SCloudregionManager) newFromCloudRegion(ctx context.Context, user log.Errorf("newFromCloudRegion fail %s", err) return nil, err } + + err = manager.SyncI18ns(ctx, userCred, ®ion, cloudRegion.GetI18n()) + if err != nil { + return nil, errors.Wrap(err, "SyncI18ns") + } + db.OpsLog.LogEvent(®ion, db.ACT_CREATE, region.GetShortDesc(ctx), userCred) return ®ion, nil } @@ -872,7 +890,12 @@ func (self *SCloudregion) GetRegionCloudenvInfo() api.CloudenvResourceInfo { return info } -func (self *SCloudregion) GetRegionInfo() api.CloudregionResourceInfo { +func (self *SCloudregion) GetI18N(ctx context.Context) *jsonutils.JSONDict { + return self.GetModelI18N(ctx, self) +} + +func (self *SCloudregion) GetRegionInfo(ctx context.Context) api.CloudregionResourceInfo { + // name := self.nameI18nLookup(ctx) return api.CloudregionResourceInfo{ Region: self.Name, Cloudregion: self.Name, diff --git a/pkg/compute/models/i18nresource.go b/pkg/compute/models/i18nresource.go new file mode 100644 index 0000000000..40d52edd6a --- /dev/null +++ b/pkg/compute/models/i18nresource.go @@ -0,0 +1,64 @@ +package models + +import ( + "context" + + "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/pkg/errors" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/mcclient" +) + +type SI18nResourceBase struct { +} + +type SI18nResourceBaseManager struct { +} + +func (man *SI18nResourceBaseManager) getSModelI18nTable(model db.IModel, table cloudprovider.SModelI18nTable) *db.SModelI18nTable { + entries := make([]db.IModelI18nEntry, 0) + for k, _ := range table { + entries = append(entries, db.NewSModelI18nEntry(k, model, table[k])) + } + + return db.NewSModelI18nTable(entries) +} + +func (man *SI18nResourceBaseManager) SyncI18ns(ctx context.Context, userCred mcclient.TokenCredential, model db.IModel, table cloudprovider.SModelI18nTable) error { + itable := man.getSModelI18nTable(model, table) + _, _, r := db.I18nManager.SyncI18ns(ctx, userCred, model, itable) + if r.IsError() { + log.Infof("SyncI18ns for %s %s result: %s", model.Keyword(), model.GetId(), r.Result()) + return errors.Wrap(r.AllError(), "SyncI18ns") + } + + log.Debugf("SyncI18ns for %s %s result: %s", model.Keyword(), model.GetId(), r.Result()) + return nil +} + +func (self *SI18nResourceBase) RemoveI18ns(ctx context.Context, userCred mcclient.TokenCredential, model db.IModel) error { + err := db.I18nManager.RemoveI18ns(ctx, userCred, model) + if err != nil { + return errors.Wrap(err, "RemoveI18ns") + } + + return nil +} + +func (self *SI18nResourceBase) GetModelI18N(ctx context.Context, model db.IModel) *jsonutils.JSONDict { + entries, err := db.I18nManager.GetModelI18N(ctx, model) + if err != nil { + log.Infof("GetI18N %s", err) + return nil + } + + _i18n := jsonutils.NewDict() + for i := range entries { + _i18n.Set(entries[i].KeyName, jsonutils.NewString(entries[i].Lookup(ctx))) + } + + return _i18n +} diff --git a/pkg/compute/models/skus.go b/pkg/compute/models/skus.go index 446eca76f3..f26bb8aeec 100644 --- a/pkg/compute/models/skus.go +++ b/pkg/compute/models/skus.go @@ -1168,6 +1168,7 @@ func (manager *SServerSkuManager) newPublicCloudSku(ctx context.Context, userCre func (self *SServerSku) syncWithCloudSku(ctx context.Context, userCred mcclient.TokenCredential, extSku SServerSku) error { _, err := db.Update(self, func() error { self.ZoneId = extSku.ZoneId + self.InstanceTypeCategory = extSku.InstanceTypeCategory self.PrepaidStatus = extSku.PrepaidStatus self.PostpaidStatus = extSku.PostpaidStatus self.SysDiskType = extSku.SysDiskType diff --git a/pkg/compute/models/zones.go b/pkg/compute/models/zones.go index 381110d4dd..e3e36ffbba 100644 --- a/pkg/compute/models/zones.go +++ b/pkg/compute/models/zones.go @@ -39,6 +39,7 @@ import ( type SZoneManager struct { db.SStatusStandaloneResourceBaseManager db.SExternalizedResourceBaseManager + SI18nResourceBaseManager SCloudregionResourceBaseManager } @@ -60,6 +61,7 @@ func init() { type SZone struct { db.SStatusStandaloneResourceBase db.SExternalizedResourceBase + SI18nResourceBase SCloudregionResourceBase `width:"36" charset:"ascii" nullable:"false" list:"user" create:"admin_required"` Location string `width:"256" charset:"utf8" get:"user" list:"user" update:"admin"` @@ -184,6 +186,10 @@ func (zone *SZone) GetCloudRegionId() string { } } +func (zone *SZone) GetI18N(ctx context.Context) *jsonutils.JSONDict { + return zone.GetModelI18N(ctx, zone) +} + func (manager *SZoneManager) SyncZones(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, zones []cloudprovider.ICloudZone) ([]SZone, []cloudprovider.ICloudZone, compare.SyncResult) { lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred)) defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred)) @@ -247,7 +253,12 @@ func (self *SZone) syncRemoveCloudZone(ctx context.Context, userCred mcclient.To lockman.LockObject(ctx, self) defer lockman.ReleaseObject(ctx, self) - err := self.ValidateDeleteCondition(ctx) + err := self.RemoveI18ns(ctx, userCred, self) + if err != nil { + return err + } + + err = self.ValidateDeleteCondition(ctx) if err != nil { // cannot delete err = self.SetStatus(userCred, api.ZONE_DISABLE, "sync to delete") } else { @@ -257,12 +268,16 @@ func (self *SZone) syncRemoveCloudZone(ctx context.Context, userCred mcclient.To } func (self *SZone) syncWithCloudZone(ctx context.Context, userCred mcclient.TokenCredential, extZone cloudprovider.ICloudZone, region *SCloudregion) error { + err := ZoneManager.SyncI18ns(ctx, userCred, self, extZone.GetI18n()) + if err != nil { + return errors.Wrap(err, "SyncI18ns") + } + diff, err := db.UpdateWithLock(ctx, self, func() error { self.Name = extZone.GetName() self.Status = extZone.GetStatus() self.IsEmulated = extZone.IsEmulated() - self.CloudregionId = region.Id return nil @@ -296,6 +311,12 @@ func (manager *SZoneManager) newFromCloudZone(ctx context.Context, userCred mccl log.Errorf("newFromCloudZone fail %s", err) return nil, err } + + err = manager.SyncI18ns(ctx, userCred, &zone, extZone.GetI18n()) + if err != nil { + return nil, errors.Wrap(err, "SyncI18ns") + } + db.OpsLog.LogEvent(&zone, db.ACT_CREATE, zone.GetShortDesc(ctx), userCred) return &zone, nil } diff --git a/pkg/compute/service/handlers.go b/pkg/compute/service/handlers.go index 58e36b82ad..ad3f5b1047 100644 --- a/pkg/compute/service/handlers.go +++ b/pkg/compute/service/handlers.go @@ -57,6 +57,7 @@ func InitHandlers(app *appsrv.Application) { db.UserCacheManager, db.TenantCacheManager, db.SharedResourceManager, + db.I18nManager, models.GuestcdromManager, models.NetInterfaceManager, models.VCenterManager, diff --git a/pkg/hostman/guestman/forwarder/api/forwarder.pb.go b/pkg/hostman/guestman/forwarder/api/forwarder.pb.go index b964fbf567..98be03cca4 100644 --- a/pkg/hostman/guestman/forwarder/api/forwarder.pb.go +++ b/pkg/hostman/guestman/forwarder/api/forwarder.pb.go @@ -7,10 +7,11 @@ package api import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( diff --git a/pkg/hostman/guestman/forwarder/api/forwarder_grpc.pb.go b/pkg/hostman/guestman/forwarder/api/forwarder_grpc.pb.go index 0e9c59f837..25af0b9d16 100644 --- a/pkg/hostman/guestman/forwarder/api/forwarder_grpc.pb.go +++ b/pkg/hostman/guestman/forwarder/api/forwarder_grpc.pb.go @@ -4,6 +4,7 @@ package api import ( context "context" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/pkg/i18n/table.go b/pkg/i18n/table.go index afc030ed32..e0841df4e4 100644 --- a/pkg/i18n/table.go +++ b/pkg/i18n/table.go @@ -6,6 +6,13 @@ import ( "golang.org/x/text/language" ) +type Tag = language.Tag + +var ( + I18N_TAG_CHINESE Tag = Tag(language.Chinese) + I18N_TAG_ENGLISH Tag = Tag(language.English) +) + type ITable interface { Lookup(ctx context.Context, key string) string } @@ -27,6 +34,14 @@ func (te TableEntry) EN(v string) TableEntry { return te } +func (te TableEntry) Lookup(ctx context.Context) (string, bool) { + lang := Lang(ctx) + lang = tableLangMatch(lang) + + v, ok := te[lang] + return v, ok +} + func (tbl Table) Set(k string, te TableEntry) { tbl[k] = te } @@ -41,11 +56,13 @@ func (tbl Table) LookupByLang(lang language.Tag, key string) string { if !ok { return key } + lang = tableLangMatch(lang) v, ok := te[lang] if !ok { return key } + return v } diff --git a/pkg/multicloud/aliyun/aliyun.go b/pkg/multicloud/aliyun/aliyun.go index f80b667296..f4c988c5fc 100644 --- a/pkg/multicloud/aliyun/aliyun.go +++ b/pkg/multicloud/aliyun/aliyun.go @@ -41,6 +41,7 @@ const ( CLOUD_PROVIDER_ALIYUN = api.CLOUD_PROVIDER_ALIYUN CLOUD_PROVIDER_ALIYUN_CN = "阿里云" + CLOUD_PROVIDER_ALIYUN_EN = "Aliyun" ALIYUN_DEFAULT_REGION = "cn-hangzhou" diff --git a/pkg/multicloud/aliyun/region.go b/pkg/multicloud/aliyun/region.go index f5fe48a530..45c5f39792 100644 --- a/pkg/multicloud/aliyun/region.go +++ b/pkg/multicloud/aliyun/region.go @@ -244,6 +244,13 @@ func (self *SRegion) GetName() string { } } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_ALIYUN_EN, self.LocalName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.RegionId) } diff --git a/pkg/multicloud/aliyun/zone.go b/pkg/multicloud/aliyun/zone.go index 05e460a35a..6182f598ef 100644 --- a/pkg/multicloud/aliyun/zone.go +++ b/pkg/multicloud/aliyun/zone.go @@ -152,6 +152,12 @@ func (self *SZone) GetName() string { } } +func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()) + return table +} + func (self *SZone) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.region.GetGlobalId(), self.ZoneId) } diff --git a/pkg/multicloud/apsara/apsara.go b/pkg/multicloud/apsara/apsara.go index 853911ae51..01c58c432c 100644 --- a/pkg/multicloud/apsara/apsara.go +++ b/pkg/multicloud/apsara/apsara.go @@ -39,6 +39,7 @@ import ( const ( CLOUD_PROVIDER_APSARA = api.CLOUD_PROVIDER_APSARA CLOUD_PROVIDER_APSARA_CN = "阿里云专有云" + CLOUD_PROVIDER_APSARA_EN = "Aliyun Apsara" APSARA_API_VERSION = "2014-05-26" APSARA_API_VERSION_VPC = "2016-04-28" diff --git a/pkg/multicloud/apsara/region.go b/pkg/multicloud/apsara/region.go index c7cf6c2305..afc3937df2 100644 --- a/pkg/multicloud/apsara/region.go +++ b/pkg/multicloud/apsara/region.go @@ -173,6 +173,13 @@ func (self *SRegion) GetName() string { } } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_APSARA_EN, self.LocalName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_APSARA, self.RegionId) } diff --git a/pkg/multicloud/apsara/zone.go b/pkg/multicloud/apsara/zone.go index e8dfcb2f70..9fe1aceb49 100644 --- a/pkg/multicloud/apsara/zone.go +++ b/pkg/multicloud/apsara/zone.go @@ -139,6 +139,13 @@ func (self *SZone) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_APSARA_CN, self.LocalName) } +func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_APSARA_EN, self.LocalName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SZone) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.region.GetGlobalId(), self.ZoneId) } diff --git a/pkg/multicloud/aws/aws.go b/pkg/multicloud/aws/aws.go index 5d76c2ab38..15792ab6bc 100644 --- a/pkg/multicloud/aws/aws.go +++ b/pkg/multicloud/aws/aws.go @@ -43,6 +43,7 @@ import ( const ( CLOUD_PROVIDER_AWS = api.CLOUD_PROVIDER_AWS CLOUD_PROVIDER_AWS_CN = "AWS" + CLOUD_PROVIDER_AWS_EN = "AWS" AWS_INTERNATIONAL_CLOUDENV = "InternationalCloud" AWS_CHINA_CLOUDENV = "ChinaCloud" diff --git a/pkg/multicloud/aws/region.go b/pkg/multicloud/aws/region.go index a355d86282..d1184e5458 100644 --- a/pkg/multicloud/aws/region.go +++ b/pkg/multicloud/aws/region.go @@ -73,6 +73,33 @@ var RegionLocations = map[string]string{ "us-gov-east-1": "AWS GovCloud(美国东部)", } +var RegionLocationsEN = map[string]string{ + "us-east-1": "US East (N. Virginia)", + "us-east-2": "US East (Ohio)", + "us-west-1": "US West (N. California)", + "us-west-2": "US West (Oregon)", + "af-south-1": "Cape Town", + "ap-east-1": "Asia Pacific (Hong Kong)", + "ap-south-1": "Asia Pacific (Mumbai)", + "ap-northeast-2": "Asia Pacific (Seoul)", + "ap-southeast-1": "Asia Pacific (Singapore)", + "ap-southeast-2": "Asia Pacific (Sydney)", + "ap-northeast-1": "Asia Pacific (Tokyo)", + "ca-central-1": "Canada (Central)", + "eu-central-1": "Europe (Frankfurt)", + "eu-west-1": "Europe (Ireland)", + "eu-west-2": "Europe (London)", + "eu-south-1": "Europe (Milan)", + "eu-west-3": "Europe (Paris)", + "eu-north-1": "Europe (Stockholm)", + "me-south-1": "Middle East (Bahrain)", + "sa-east-1": "South America (São Paulo)", + "cn-north-1": "China (Beijing)", + "cn-northwest-1": "China (Ninxia)", + "us-gov-west-1": "AWS GovCloud(US West)", + "us-gov-east-1": "AWS GovCloud(US East)", +} + const ( RDS_SERVICE_NAME = "rds" RDS_SERVICE_ID = "RDS" @@ -420,6 +447,19 @@ func (self *SRegion) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_AWS_CN, self.RegionId) } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + var en string + if localName, ok := RegionLocationsEN[self.RegionId]; ok { + en = fmt.Sprintf("%s %s", CLOUD_PROVIDER_AWS_EN, localName) + } else { + en = fmt.Sprintf("%s %s", CLOUD_PROVIDER_AWS_EN, self.RegionId) + } + + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.RegionId) } diff --git a/pkg/multicloud/aws/zone.go b/pkg/multicloud/aws/zone.go index c5017c8e3a..3b06c43065 100644 --- a/pkg/multicloud/aws/zone.go +++ b/pkg/multicloud/aws/zone.go @@ -113,6 +113,13 @@ func (self *SZone) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_AWS_CN, self.LocalName) } +func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_AWS_EN, self.LocalName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SZone) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.region.GetGlobalId(), self.ZoneId) } diff --git a/pkg/multicloud/azure/azure.go b/pkg/multicloud/azure/azure.go index 5c046328fd..7da493044d 100644 --- a/pkg/multicloud/azure/azure.go +++ b/pkg/multicloud/azure/azure.go @@ -40,6 +40,7 @@ import ( const ( CLOUD_PROVIDER_AZURE = api.CLOUD_PROVIDER_AZURE CLOUD_PROVIDER_AZURE_CN = "微软" + CLOUD_PROVIDER_AZURE_EN = "Azure" AZURE_API_VERSION = "2016-02-01" ) diff --git a/pkg/multicloud/azure/region.go b/pkg/multicloud/azure/region.go index 9816fd998c..27f38c0682 100644 --- a/pkg/multicloud/azure/region.go +++ b/pkg/multicloud/azure/region.go @@ -106,6 +106,13 @@ func (self *SRegion) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_AZURE_CN, self.DisplayName) } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_AZURE_EN, self.DisplayName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.Name) } diff --git a/pkg/multicloud/azure/zone.go b/pkg/multicloud/azure/zone.go index f64e481ba9..0acef3de79 100644 --- a/pkg/multicloud/azure/zone.go +++ b/pkg/multicloud/azure/zone.go @@ -37,6 +37,10 @@ func (self *SZone) GetName() string { return self.region.GetName() } +func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { + return self.region.GetI18n() +} + func (self *SZone) GetGlobalId() string { return self.region.GetGlobalId() } diff --git a/pkg/multicloud/ctyun/ctyun.go b/pkg/multicloud/ctyun/ctyun.go index db59bd976b..fd2e90ee97 100644 --- a/pkg/multicloud/ctyun/ctyun.go +++ b/pkg/multicloud/ctyun/ctyun.go @@ -39,6 +39,7 @@ const ( CTYUN_API_HOST = "https://api.ctyun.cn" CLOUD_PROVIDER_CTYUN = api.CLOUD_PROVIDER_CTYUN CLOUD_PROVIDER_CTYUN_CN = "天翼云" + CLOUD_PROVIDER_CTYUN_EN = "Ctyun" CTYUN_DEFAULT_REGION = "cn-bj4" CTYUN_API_VERSION = "2019-11-22" diff --git a/pkg/multicloud/ctyun/region.go b/pkg/multicloud/ctyun/region.go index f27e1e9815..9813dbcef9 100644 --- a/pkg/multicloud/ctyun/region.go +++ b/pkg/multicloud/ctyun/region.go @@ -163,6 +163,13 @@ func (self *SRegion) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_CTYUN_CN, self.RegionName) } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_CTYUN_EN, self.RegionName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.ID) } diff --git a/pkg/multicloud/ctyun/zone.go b/pkg/multicloud/ctyun/zone.go index c742a45e56..73b0292ed6 100644 --- a/pkg/multicloud/ctyun/zone.go +++ b/pkg/multicloud/ctyun/zone.go @@ -58,6 +58,12 @@ func (self *SZone) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_CTYUN_CN, self.ZoneID) } +func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(self.ZoneID) + return table +} + func (self *SZone) GetGlobalId() string { return getZoneGlobalId(self.region, self.GetId()) } diff --git a/pkg/multicloud/esxi/manager.go b/pkg/multicloud/esxi/manager.go index 9dcd926ed7..43fa2157ae 100644 --- a/pkg/multicloud/esxi/manager.go +++ b/pkg/multicloud/esxi/manager.go @@ -247,6 +247,12 @@ func (cli *SESXiClient) GetAccountId() string { return fmt.Sprintf("%s@%s:%d", cli.account, cli.host, cli.port) } +func (cli *SESXiClient) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(cli.GetName()).CN(cli.GetName()) + return table +} + func (cli *SESXiClient) GetVersion() string { return cli.client.ServiceContent.About.Version } diff --git a/pkg/multicloud/google/region.go b/pkg/multicloud/google/region.go index 7397cc1a15..98110e8770 100644 --- a/pkg/multicloud/google/region.go +++ b/pkg/multicloud/google/region.go @@ -57,6 +57,13 @@ func (region *SRegion) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_GOOGLE_CN, region.Name) } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_GOOGLE, self.Name) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (region *SRegion) GetId() string { return region.Name } diff --git a/pkg/multicloud/google/zone.go b/pkg/multicloud/google/zone.go index 143b404d5d..23ff1ba35b 100644 --- a/pkg/multicloud/google/zone.go +++ b/pkg/multicloud/google/zone.go @@ -55,6 +55,12 @@ func (zone *SZone) GetName() string { return zone.Name } +func (zone *SZone) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(zone.GetName()).CN(zone.GetName()) + return table +} + func (zone *SZone) GetGlobalId() string { return fmt.Sprintf("%s/%s", zone.region.GetGlobalId(), zone.Name) } diff --git a/pkg/multicloud/huawei/huawei.go b/pkg/multicloud/huawei/huawei.go index 9fd30e657e..49ca71984e 100644 --- a/pkg/multicloud/huawei/huawei.go +++ b/pkg/multicloud/huawei/huawei.go @@ -41,6 +41,7 @@ import ( const ( CLOUD_PROVIDER_HUAWEI = api.CLOUD_PROVIDER_HUAWEI CLOUD_PROVIDER_HUAWEI_CN = "华为云" + CLOUD_PROVIDER_HUAWEI_EN = "Huawei" HUAWEI_INTERNATIONAL_CLOUDENV = "InternationalCloud" HUAWEI_CHINA_CLOUDENV = "ChinaCloud" diff --git a/pkg/multicloud/huawei/region.go b/pkg/multicloud/huawei/region.go index aeae4a076f..4d650a2c54 100644 --- a/pkg/multicloud/huawei/region.go +++ b/pkg/multicloud/huawei/region.go @@ -355,6 +355,13 @@ func (self *SRegion) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_HUAWEI_CN, self.Locales.ZhCN) } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_HUAWEI_EN, self.Locales.EnUs) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.client.GetAccessEnv(), self.ID) } diff --git a/pkg/multicloud/huawei/zone.go b/pkg/multicloud/huawei/zone.go index 3fc071b58b..6d1f591010 100644 --- a/pkg/multicloud/huawei/zone.go +++ b/pkg/multicloud/huawei/zone.go @@ -95,6 +95,13 @@ func (self *SZone) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_HUAWEI_CN, self.ZoneName) } +func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_HUAWEI_EN, self.ZoneName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SZone) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.region.GetGlobalId(), self.ZoneName) } diff --git a/pkg/multicloud/objectstore/objectstore.go b/pkg/multicloud/objectstore/objectstore.go index b5ed687a57..c523c0f4c6 100644 --- a/pkg/multicloud/objectstore/objectstore.go +++ b/pkg/multicloud/objectstore/objectstore.go @@ -166,6 +166,12 @@ func (cli *SObjectStoreClient) GetIBucketProvider() IBucketProvider { return cli.GetVirtualObject().(IBucketProvider) } +func (cli *SObjectStoreClient) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(cli.GetName()).CN(cli.GetName()) + return table +} + func (cli *SObjectStoreClient) GetVersion() string { return "" } diff --git a/pkg/multicloud/openstack/region.go b/pkg/multicloud/openstack/region.go index fb86772aa9..cac1692ff4 100644 --- a/pkg/multicloud/openstack/region.go +++ b/pkg/multicloud/openstack/region.go @@ -67,6 +67,12 @@ func (region *SRegion) GetName() string { return fmt.Sprintf("%s-%s", region.client.cpcfg.Name, region.Name) } +func (region *SRegion) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(region.GetName()).CN(region.GetName()) + return table +} + func (region *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s/%s", CLOUD_PROVIDER_OPENSTACK, region.client.cpcfg.Id, region.Name) } diff --git a/pkg/multicloud/openstack/zone.go b/pkg/multicloud/openstack/zone.go index a55f0e5f2d..2a4a297310 100644 --- a/pkg/multicloud/openstack/zone.go +++ b/pkg/multicloud/openstack/zone.go @@ -57,6 +57,12 @@ func (zone *SZone) GetName() string { return zone.ZoneName } +func (zone *SZone) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(zone.GetName()).CN(zone.GetName()) + return table +} + func (zone *SZone) GetGlobalId() string { return fmt.Sprintf("%s/%s/%s", CLOUD_PROVIDER_OPENSTACK, zone.region.Name, zone.ZoneName) } diff --git a/pkg/multicloud/qcloud/qcloud.go b/pkg/multicloud/qcloud/qcloud.go index 7133455ea7..9fde29f48e 100644 --- a/pkg/multicloud/qcloud/qcloud.go +++ b/pkg/multicloud/qcloud/qcloud.go @@ -45,6 +45,7 @@ import ( const ( CLOUD_PROVIDER_QCLOUD = api.CLOUD_PROVIDER_QCLOUD CLOUD_PROVIDER_QCLOUD_CN = "腾讯云" + CLOUD_PROVIDER_QCLOUD_EN = "QCloud" QCLOUD_DEFAULT_REGION = "ap-beijing" diff --git a/pkg/multicloud/qcloud/region.go b/pkg/multicloud/qcloud/region.go index 25610c868f..f28501cbe4 100644 --- a/pkg/multicloud/qcloud/region.go +++ b/pkg/multicloud/qcloud/region.go @@ -223,6 +223,13 @@ func (self *SRegion) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_QCLOUD_CN, self.RegionName) } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_QCLOUD_EN, self.RegionName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_QCLOUD, self.Region) } diff --git a/pkg/multicloud/qcloud/zone.go b/pkg/multicloud/qcloud/zone.go index 64a7381189..6aaafe0b18 100644 --- a/pkg/multicloud/qcloud/zone.go +++ b/pkg/multicloud/qcloud/zone.go @@ -65,6 +65,13 @@ func (self *SZone) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_QCLOUD_CN, self.ZoneName) } +func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { + en := fmt.Sprintf("%s %s", CLOUD_PROVIDER_QCLOUD_EN, self.ZoneName) + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SZone) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.region.GetGlobalId(), self.Zone) } diff --git a/pkg/multicloud/ucloud/consts.go b/pkg/multicloud/ucloud/consts.go index 8a8a5b2677..595adc5647 100644 --- a/pkg/multicloud/ucloud/consts.go +++ b/pkg/multicloud/ucloud/consts.go @@ -41,6 +41,32 @@ var UCLOUD_REGION_NAMES = map[string]string{ "vn-sng": "胡志明市", } +var UCLOUD_REGION_NAMES_EN = map[string]string{ + "cn-bj1": "Beijing 1", + "cn-bj2": "Beijing 2", + "cn-sh": "Shanghai 1", + "cn-sh2": "Shanghai 2", + "cn-gd": "Guangzhou", + "hk": "Hongkong", + "us-ca": "Los Angeles", + "us-ws": "Washington", + "ge-fra": "Frankfurt", + "th-bkk": "Bangkok", + "kr-seoul": "Seoul", + "sg": "Singapore", + "tw-tp": "TaiPei", + "tw-kh": "Gaoxiong", + "jpn-tky": "Tokyo", + "rus-mosc": "Moscow", + "uae-dubai": "Dubai", + "idn-jakarta": "Jakarta", + "ind-mumbai": "Mumbai", + "bra-saopaulo": "Sao Paulo", + "uk-london": "London", + "afr-nigeria": "Lagos", + "vn-sng": "Ho Chi Min City", +} + var UCLOUD_ZONE_NAMES = map[string]string{ "cn-bj1-01": "北京一可用区A", "cn-bj2-02": "北京二可用区B", @@ -71,3 +97,34 @@ var UCLOUD_ZONE_NAMES = map[string]string{ "afr-nigeria-01": "拉各斯可用区A", "vn-sng-01": "胡志明市可用区A", } + +var UCLOUD_ZONE_NAMES_EN = map[string]string{ + "cn-bj1-01": "Beijing 1 Zone A", + "cn-bj2-02": "Beijing 2 Zone B", + "cn-bj2-03": "Beijing 2 Zone C", + "cn-bj2-04": "Beijing 2 Zone D", + "cn-bj2-05": "Beijing 2 Zone E", + "cn-sh-01": "Shanghai 1 Zone A", + "cn-sh2-01": "Shanghai 2 Zone A", + "cn-sh2-02": "Shanghai 2 Zone B", + "cn-gd-02": "Guangzhou Zone B", + "hk-01": "Hongkong Zone A", + "hk-02": "Hongkong Zone B", + "us-ca-01": "Los Angeles Zone A", + "us-ws-01": "Washington Zone A", + "ge-fra-01": "Frankfurt Zone A", + "th-bkk-01": "Bangkok Zone A", + "kr-seoul-01": "Seoul Zone A", + "sg-01": "Singapore Zone A", + "tw-kh-01": "Gaoxiong Zone A", + "tw-tp-01": "TaiPei Zone A", + "jpn-tky-01": "Tokyo Zone A", + "rus-mosc-01": "Moscow Zone A", + "uae-dubai-01": "Dubai Zone A", + "idn-jakarta-01": "Jakarta Zone A", + "ind-mumbai-01": "Mumbai Zone A", + "bra-saopaulo-01": "Sao Paulo Zone A", + "uk-london-01": "London Zone A", + "afr-nigeria-01": "Lagos Zone A", + "vn-sng-01": "Ho Chi Min City Zone A", +} diff --git a/pkg/multicloud/ucloud/region.go b/pkg/multicloud/ucloud/region.go index 680ed40ecc..0eb96130aa 100644 --- a/pkg/multicloud/ucloud/region.go +++ b/pkg/multicloud/ucloud/region.go @@ -58,6 +58,19 @@ func (self *SRegion) GetName() string { return fmt.Sprintf("%s %s", CLOUD_PROVIDER_UCLOUD_CN, self.GetId()) } +func (self *SRegion) GetI18n() cloudprovider.SModelI18nTable { + var en string + if name, exist := UCLOUD_REGION_NAMES_EN[self.GetId()]; exist { + en = fmt.Sprintf("%s %s", CLOUD_PROVIDER_UCLOUD, name) + } else { + en = fmt.Sprintf("%s %s", CLOUD_PROVIDER_UCLOUD, self.GetId()) + } + + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_UCLOUD, self.GetId()) } diff --git a/pkg/multicloud/ucloud/zone.go b/pkg/multicloud/ucloud/zone.go index b069a8542e..eb85cd2fb5 100644 --- a/pkg/multicloud/ucloud/zone.go +++ b/pkg/multicloud/ucloud/zone.go @@ -91,6 +91,19 @@ func (self *SZone) GetName() string { return self.GetId() } +func (self *SZone) GetI18n() cloudprovider.SModelI18nTable { + var en string + if name, exists := UCLOUD_ZONE_NAMES_EN[self.GetId()]; exists { + en = name + } else { + en = self.GetId() + } + + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(self.GetName()).CN(self.GetName()).EN(en) + return table +} + func (self *SZone) GetGlobalId() string { return fmt.Sprintf("%s/%s", self.region.GetGlobalId(), self.GetId()) } diff --git a/pkg/multicloud/zstack/region.go b/pkg/multicloud/zstack/region.go index 1a72320734..4b216c2aff 100644 --- a/pkg/multicloud/zstack/region.go +++ b/pkg/multicloud/zstack/region.go @@ -55,6 +55,12 @@ func (region *SRegion) GetName() string { return region.client.cpcfg.Name } +func (region *SRegion) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(region.GetName()).CN(region.GetName()) + return table +} + func (region *SRegion) GetGlobalId() string { return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_ZSTACK, region.client.cpcfg.Id) } diff --git a/pkg/multicloud/zstack/zone.go b/pkg/multicloud/zstack/zone.go index b74817e9d0..cca0385783 100644 --- a/pkg/multicloud/zstack/zone.go +++ b/pkg/multicloud/zstack/zone.go @@ -50,6 +50,12 @@ func (zone *SZone) GetName() string { return zone.Name } +func (zone *SZone) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(zone.GetName()).CN(zone.GetName()) + return table +} + func (zone *SZone) GetGlobalId() string { return zone.GetId() }