diff --git a/pkg/apis/cloudprovider/zz_generated.model.go b/pkg/apis/cloudprovider/zz_generated.model.go index eeaf89b450..7d5dfcdf6f 100644 --- a/pkg/apis/cloudprovider/zz_generated.model.go +++ b/pkg/apis/cloudprovider/zz_generated.model.go @@ -14,6 +14,8 @@ package cloudprovider +import "yunion.io/x/onecloud/pkg/cloudprovider" + // DefaultAction is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.DefaultAction. type DefaultAction struct { // Allow, Block, Log, Count, Alert, Detection, Prevention @@ -28,6 +30,37 @@ type DefaultAction struct { ResponseHeaders map[string]string `json:"response_headers"` } +// SCdnDomain is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.SCdnDomain. +type SCdnDomain struct { + // cdn加速域名 + Domain string `json:"domain"` + // 状态 rejected(域名未审核)|processing(部署中)|online|offline + Status string `json:"status"` + // 区域 mainland|overseas|global + Area string `json:"area"` + // cdn Cname + Cname string `json:"cname"` + // 源站 + Origin string `json:"origin"` + // 源站类型 domain|ip|bucket + OriginType string `json:"origin_type"` +} + +// SCdnOrigin is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.SCdnOrigin. +type SCdnOrigin struct { + Type string `json:"type"` + Origin string `json:"origin"` + ServerName string `json:"server_name"` + Protocol string `json:"protocol"` + Path string `json:"path"` + Port int `json:"port"` + Enabled string `json:"enabled"` + Priority int `json:"priority"` +} + +// SCdnOrigins is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.SCdnOrigins. +type SCdnOrigins []SCdnOrigin + // SExcludeRule is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.SExcludeRule. type SExcludeRule struct { Name string `json:"name"` @@ -52,6 +85,17 @@ type SGeographicInfo struct { CountryCode string `json:"country_code"` } +// SSubAccount is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.SSubAccount. +type SSubAccount struct { + // 若Account不为空,可不传 + Name string `json:"name"` + // 输入必填,若为空,需要指定子账号名称 + Account string `json:"account"` + HealthStatus string `json:"health_status"` + // 云端服务健康状态。例如欠费、项目冻结都属于不健康状态。 + DefaultProjectId string `json:"default_project_id"` +} + // SWafStatement is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.SWafStatement. type SWafStatement struct { // 管理规则组名称 @@ -86,6 +130,48 @@ type SWafStatement struct { RuleGroupId string `json:"rule_group_id"` } +// ServerVncInput is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.ServerVncInput. +type ServerVncInput struct { + // 是否使用原生vnc控制台,此选项仅对openstack有效 + // default: false + Origin bool `json:"origin"` +} + +// ServerVncOutput is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.ServerVncOutput. +type ServerVncOutput struct { + Id string `json:"id"` + // baremetal + HostId string `json:"host_id"` + Zone string `json:"zone"` + // kvm host ip + Host string `json:"host"` + Protocol string `json:"protocol"` + Port int64 `json:"port"` + Url string `json:"url"` + InstanceId string `json:"instance_id"` + InstanceName string `json:"instance_name"` + Password string `json:"password"` + VncPassword string `json:"vnc_password"` + OsName string `json:"os_name"` + // cloudpods + ApiServer string `json:"api_server"` + ConnectParams string `json:"connect_params"` + Session string `json:"session"` + Hypervisor string `json:"hypervisor"` +} + +// SubAccounts is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.SubAccounts. +type SubAccounts struct { + // 若输出则是全量子账号列表,若输入,代表允许同步的子账号 + Accounts []cloudprovider.SSubAccount `json:"accounts"` + // 若输出是云账号查询到的区域列表,若输入,代表允许同步的区域 + Cloudregions []struct { + Id string + Name string + Status string + } `json:"cloudregions"` +} + // TWafAction is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudprovider.TWafAction. type TWafAction string diff --git a/pkg/apis/compute/api.go b/pkg/apis/compute/api.go index 5f8cc7b935..875526a331 100644 --- a/pkg/apis/compute/api.go +++ b/pkg/apis/compute/api.go @@ -348,6 +348,7 @@ type DeployConfig struct { type ServerCreateInput struct { apis.VirtualResourceCreateInput DeletePreventableCreateInput + HostnameInput *ServerConfigs diff --git a/pkg/apis/compute/guests.go b/pkg/apis/compute/guests.go index 259ccf55e6..45f59c9301 100644 --- a/pkg/apis/compute/guests.go +++ b/pkg/apis/compute/guests.go @@ -625,6 +625,7 @@ type ServerUpdateInput struct { type GuestJsonDesc struct { Name string `json:"name"` + Hostname string `json:"hostname"` Description string `json:"description"` UUID string `json:"uuid"` Mem int `json:"mem"` diff --git a/pkg/apis/compute/host.go b/pkg/apis/compute/host.go index 04daa89b5f..87af968afa 100644 --- a/pkg/apis/compute/host.go +++ b/pkg/apis/compute/host.go @@ -347,6 +347,7 @@ type HostCreateInput struct { apis.EnabledStatusInfrasResourceBaseCreateInput ZoneResourceInput + HostnameInput HostAccessAttributes HostSizeAttributes diff --git a/pkg/apis/compute/input.go b/pkg/apis/compute/input.go index 9b80a7e02b..858c9a7a69 100644 --- a/pkg/apis/compute/input.go +++ b/pkg/apis/compute/input.go @@ -171,3 +171,15 @@ type DnsRecordDetails struct { SDnsRecord } + +type HostnameInput struct { + // 主机名 + // 点号(.)和短横线(-)不能作为 HostName 的首尾字符,不能连续使用 + // 字符长度2-60个字符 + // Windows: 字符长度2-15, 允许大小写英文字母, 数字和短横线, 不支持点号(.),不能全是数字 + // 若输入为空,则会根据资源名称自动生成主机名 + // 输入不为空则会自动剔除不符合规则的字符, 并进行校验 + // 若长度大于允许的最大长度,会自动截取 + // required: false + Hostname string `json:"hostname"` +} diff --git a/pkg/apis/compute/zz_generated.model.go b/pkg/apis/compute/zz_generated.model.go index 3d403afb63..712622ba02 100644 --- a/pkg/apis/compute/zz_generated.model.go +++ b/pkg/apis/compute/zz_generated.model.go @@ -60,6 +60,27 @@ type SAccessGroupRule struct { Description string `json:"description"` } +// SApp is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SApp. +type SApp struct { + apis.SVirtualResourceBase + apis.SExternalizedResourceBase + apis.SEnabledResourceBase + SManagedResourceBase + SCloudregionResourceBase + Type string `json:"type"` + TechStack string `json:"tech_stack"` + Kind string `json:"kind"` +} + +// SAppEnvironment is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SAppEnvironment. +type SAppEnvironment struct { + apis.SVirtualResourceBase + apis.SExternalizedResourceBase + AppId string `json:"app_id"` + InstanceType string `json:"instance_type"` + InstanceNumber int `json:"instance_number"` +} + // SAwsCachedLb is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SAwsCachedLb. type SAwsCachedLb struct { apis.SVirtualResourceBase @@ -141,6 +162,21 @@ type SBucket struct { AccessUrls jsonutils.JSONObject `json:"access_urls"` } +// SCDNDomain is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SCDNDomain. +type SCDNDomain struct { + apis.SEnabledStatusInfrasResourceBase + apis.SExternalizedResourceBase + SDeletePreventableResourceBase + SManagedResourceBase + Cname string `json:"cname"` + // 源站信息 + Origins *cloudprovider.SCdnOrigins `json:"origins"` + // 服务类别 + ServiceType string `json:"service_type"` + // 加速区域 + Area string `json:"area"` +} + // SCachedLoadbalancerAcl is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SCachedLoadbalancerAcl. type SCachedLoadbalancerAcl struct { apis.SVirtualResourceBase @@ -251,6 +287,8 @@ type SCloudaccount struct { IamLoginUrl string `json:"iam_login_url"` SAMLAuth *bool `json:"saml_auth,omitempty"` SProjectMappingResourceBase + // 设置允许同步的账号及订阅 + SubAccounts *cloudprovider.SubAccounts `json:"sub_accounts"` } // SCloudimage is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SCloudimage. @@ -919,6 +957,7 @@ type SExternalProject struct { apis.SVirtualResourceBase apis.SExternalizedResourceBase SManagedResourceBase + ExternalDomainId string `json:"external_domain_id"` // 归属云账号ID CloudaccountId string `json:"cloudaccount_id"` } @@ -1010,6 +1049,7 @@ type SGuest struct { SBillingResourceBase SDeletePreventableResourceBase apis.SMultiArchResourceBase + SHostnameResourceBase SHostResourceBase // CPU大小 VcpuCount int `json:"vcpu_count"` @@ -1082,20 +1122,6 @@ type SGuestTemplateResourceBase struct { GuestTemplateId string `json:"guest_template_id"` } -// SGuestcdrom is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGuestcdrom. -type SGuestcdrom struct { - Id string `json:"id"` - // = Column(VARCHAR(36, charset='ascii'), primary_key=True) - ImageId string `json:"image_id"` - // Column(VARCHAR(36, charset='ascii'), nullable=True) - Name string `json:"name"` - // Column(VARCHAR(64, charset='ascii'), nullable=True) - Path string `json:"path"` - // Column(VARCHAR(256, charset='ascii'), nullable=True) - Size int64 `json:"size"` - UpdateVersion int `json:"update_version"` -} - // SGuestdisk is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGuestdisk. type SGuestdisk struct { SGuestJointsBase @@ -1243,6 +1269,11 @@ type SHostResourceBase struct { HostId string `json:"host_id"` } +// SHostnameResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SHostnameResourceBase. +type SHostnameResourceBase struct { + Hostname string `json:"hostname"` +} + // SHostnetwork is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SHostnetwork. type SHostnetwork struct { SHostJointsBase @@ -1356,14 +1387,6 @@ type SInstanceSnapshot struct { SizeMb int `json:"size_mb"` } -// SInstanceSnapshotJoint is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SInstanceSnapshotJoint. -type SInstanceSnapshotJoint struct { - apis.SVirtualJointResourceBase - InstanceSnapshotId string `json:"instance_snapshot_id"` - SnapshotId string `json:"snapshot_id"` - DiskIndex byte `json:"disk_index"` -} - // SInterVpcNetwork is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SInterVpcNetwork. type SInterVpcNetwork struct { apis.SEnabledStatusInfrasResourceBase @@ -1466,6 +1489,31 @@ type SKeypair struct { PublicKey string `json:"public_key"` } +// SKubeCluster is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SKubeCluster. +type SKubeCluster struct { + apis.SEnabledStatusInfrasResourceBase + apis.SExternalizedResourceBase + SManagedResourceBase + SCloudregionResourceBase + // 本地KubeserverId + ExternalClusterId string `json:"external_cluster_id"` +} + +// SKubeNode is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SKubeNode. +type SKubeNode struct { + apis.SStatusStandaloneResourceBase + apis.SExternalizedResourceBase + CloudKubeNodePoolId string `json:"cloud_kube_node_pool_id"` + CloudKubeClusterId string `json:"cloud_kube_cluster_id"` +} + +// SKubeNodePool is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SKubeNodePool. +type SKubeNodePool struct { + apis.SStatusStandaloneResourceBase + apis.SExternalizedResourceBase + CloudKubeClusterId string `json:"cloud_kube_cluster_id"` +} + // SLoadbalancer is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SLoadbalancer. type SLoadbalancer struct { apis.SVirtualResourceBase @@ -1932,25 +1980,6 @@ type SNatgatewayResourceBase struct { NatgatewayId string `json:"natgateway_id"` } -// SNetInterface is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNetInterface. -type SNetInterface struct { - Mac string `json:"mac"` - // Column(VARCHAR(36, charset='ascii'), primary_key=True) - BaremetalId string `json:"baremetal_id"` - // Column(VARCHAR(36, charset='ascii'), nullable=True) - WireId string `json:"wire_id"` - // Column(VARCHAR(36, charset='ascii'), nullable=True) - Rate int `json:"rate"` - // Column(Integer, nullable=True) # Mbps - NicType string `json:"nic_type"` - // Column(VARCHAR(36, charset='ascii'), nullable=True) - Index byte `json:"index"` - // Column(TINYINT, nullable=True) - LinkUp bool `json:"link_up"` - // Column(Boolean, nullable=True) - Mtu int16 `json:"mtu"` -} - // SNetwork is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNetwork. type SNetwork struct { apis.SSharableVirtualResourceBase @@ -1965,10 +1994,12 @@ type SNetwork struct { GuestIpMask byte `json:"guest_ip_mask"` // 网关地址 GuestGateway string `json:"guest_gateway"` - // DNS + // DNS, allow multiple dns, seperated by "," GuestDns string `json:"guest_dns"` // allow multiple dhcp, seperated by "," - GuestDhcp string `json:"guest_dhcp"` + GuestDhcp string `json:"guest_dhcp"` + // allow mutiple ntp, seperated by "," + GuestNtp string `json:"guest_ntp"` GuestDomain string `json:"guest_domain"` GuestIp6Start string `json:"guest_ip6_start"` GuestIp6End string `json:"guest_ip6_end"` @@ -2537,12 +2568,17 @@ type SStoragecache struct { Path string `json:"path"` } +// SStoragecacheResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SStoragecacheResourceBase. +type SStoragecacheResourceBase struct { + // 存储缓存Id + StoragecacheId string `json:"storagecache_id"` +} + // SStoragecachedimage is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SStoragecachedimage. type SStoragecachedimage struct { apis.SJointResourceBase apis.SExternalizedResourceBase - // 存储缓存Id - StoragecacheId string `json:"storagecache_id"` + SStoragecacheResourceBase // 镜像缓存Id CachedimageId string `json:"cachedimage_id"` // 镜像状态 @@ -2613,6 +2649,8 @@ type SVpc struct { CidrBlock string `json:"cidr_block"` // Vpc外网访问模式 ExternalAccessMode string `json:"external_access_mode"` + // Can it be connected directly + Direct bool `json:"direct"` } // SVpcPeeringConnection is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SVpcPeeringConnection. diff --git a/pkg/apis/notify/zz_generated.model.go b/pkg/apis/notify/zz_generated.model.go index a4d26223a2..b658d6304b 100644 --- a/pkg/apis/notify/zz_generated.model.go +++ b/pkg/apis/notify/zz_generated.model.go @@ -73,19 +73,6 @@ type SReceiver struct { VerifiedMobile *bool `json:"verified_mobile,omitempty"` } -// SReceiverNotification is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SReceiverNotification. -type SReceiverNotification struct { - apis.SJointResourceBase - ReceiverID string `json:"receiver_id"` - NotificationID string `json:"notification_id"` - // ignore if ReceiverID is not empty or default - Contact string `json:"contact"` - ReceiverType string `json:"receiver_type"` - SendBy string `json:"send_by"` - Status string `json:"status"` - FailedReason string `json:"failed_reason"` -} - // SRobot is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SRobot. type SRobot struct { apis.SSharableVirtualResourceBase @@ -95,31 +82,19 @@ type SRobot struct { Lang string `json:"lang"` } -// SSubContact is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SSubContact. -type SSubContact struct { - apis.SStandaloneResourceBase - // id of receiver user - ReceiverID string `json:"receiver_id"` - Type string `json:"type"` - Contact string `json:"contact"` - ParentContactType string `json:"parent_contact_type"` - Enabled *bool `json:"enabled,omitempty"` - Verified *bool `json:"verified,omitempty"` - VerifiedNote string `json:"verified_note"` -} - // SSubscriber is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SSubscriber. type SSubscriber struct { apis.SStandaloneAnonResourceBase apis.SEnabledResourceBase - TopicID string `json:"topic_id"` - Type string `json:"type"` - Identification string `json:"identification"` - RoleScope string `json:"role_scope"` - ResourceScope string `json:"resource_scope"` - ResourceAttributionId string `json:"resource_attribution_id"` - Scope string `json:"scope"` - DomainId string `json:"domain_id"` + TopicID string `json:"topic_id"` + Type string `json:"type"` + Identification string `json:"identification"` + RoleScope string `json:"role_scope"` + ResourceScope string `json:"resource_scope"` + ResourceAttributionId string `json:"resource_attribution_id"` + ResourceAttributionName string `json:"resource_attribution_name"` + Scope string `json:"scope"` + DomainId string `json:"domain_id"` } // SSubscriberDis is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SSubscriberDis. @@ -152,17 +127,10 @@ type STemplate struct { type STopic struct { apis.SStandaloneResourceBase apis.SEnabledResourceBase - Type string `json:"type"` - Resources uint64 `json:"resources"` - Actions uint32 `json:"actions"` - Results byte `json:"results"` - AdvanceDays int `json:"advance_days"` -} - -// SVerification is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SVerification. -type SVerification struct { - apis.SStandaloneResourceBase - ReceiverId string `json:"receiver_id"` - ContactType string `json:"contact_type"` - Token string `json:"token"` + Type string `json:"type"` + Resources uint64 `json:"resources"` + Actions uint32 `json:"actions"` + Results byte `json:"results"` + AdvanceDays int `json:"advance_days"` + WebconsoleDisable *bool `json:"webconsole_disable,omitempty"` } diff --git a/pkg/apis/zz_generated.model.go b/pkg/apis/zz_generated.model.go index bffabb6c70..fa0117566c 100644 --- a/pkg/apis/zz_generated.model.go +++ b/pkg/apis/zz_generated.model.go @@ -103,11 +103,12 @@ type SEnabledStatusStandaloneResourceBase struct { // SExternalizedResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SExternalizedResourceBase. type SExternalizedResourceBase struct { - // 外部Id, 对用公有云私有资源自身的Id + // 云上Id, 对应云上资源自身Id ExternalId string `json:"external_id"` // 资源导入时间 ImportedAt time.Time `json:"imported_at"` - Source string `json:"source"` + // 资源来源, cloud: 从云上同步下来的资源, local: 从本地创建的资源或资源在本地更改过项目 + Source string `json:"source"` } // SI18n is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SI18n. @@ -301,6 +302,8 @@ type SStatusInfrasResourceBase struct { type SStatusResourceBase struct { // 资源状态 Status string `json:"status"` + // 操作进度0-100 + Progress float32 `json:"progress"` } // SStatusStandaloneResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SStatusStandaloneResourceBase. diff --git a/pkg/cloudcommon/db/db_dispatcher.go b/pkg/cloudcommon/db/db_dispatcher.go index 119701880a..e772518ae0 100644 --- a/pkg/cloudcommon/db/db_dispatcher.go +++ b/pkg/cloudcommon/db/db_dispatcher.go @@ -840,8 +840,7 @@ func (dispatcher *DBModelDispatcher) List(ctx context.Context, query jsonutils.J items, err := ListItems(dispatcher.modelManager, ctx, userCred, query, ctxIds) if err != nil { - log.Errorf("Fail to list items: %s", err) - return nil, httperrors.NewGeneralError(err) + return nil, httperrors.NewGeneralError(errors.Wrapf(err, "ListItems")) } if userCred != nil && userCred.HasSystemAdminPrivilege() && dispatcher.modelManager.ListSkipLog(ctx, userCred, query) { @@ -856,7 +855,6 @@ func (dispatcher *DBModelDispatcher) List(ctx context.Context, query jsonutils.J func getModelItemDetails(manager IModelManager, item IModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, isHead bool) (jsonutils.JSONObject, error) { appParams := appsrv.AppContextGetParams(ctx) if appParams == nil && isHead { - log.Errorf("fail to get http response writer???") return nil, httperrors.NewInternalServerError("fail to get http response writer from context") } hdrs := item.GetExtraDetailsHeaders(ctx, userCred, query) @@ -898,8 +896,7 @@ func getItemDetails(manager IModelManager, item IModel, ctx context.Context, use excludes, _, _ := stringutils2.Split(stringutils2.NewSortedStrings(excludeFields), getFields) return extraRows[0].CopyExcludes(excludes...), nil } - log.Errorf("FetchCustomizeColumns return incorrect number of objects %d", len(extraRows)) - return nil, httperrors.NewInternalServerError("FetchCustomizeColumns returns incorrect results") + return nil, httperrors.NewInternalServerError("FetchCustomizeColumns returns incorrect results(expect 1 actual %d)", len(extraRows)) } func (dispatcher *DBModelDispatcher) tryGetModelProperty(ctx context.Context, property string, query jsonutils.JSONObject) (jsonutils.JSONObject, error) { @@ -1175,8 +1172,7 @@ func _doCreateItem( dataDict, ok := data.(*jsonutils.JSONDict) if !ok { - log.Errorf("doCreateItem: fail to decode json data %s", data) - return nil, fmt.Errorf("fail to decode json data %s", data) + return nil, httperrors.NewGeneralError(fmt.Errorf("fail to decode json data %s", data)) } var err error @@ -1213,8 +1209,8 @@ func _doCreateItem( if batchCreate { funcName = "BatchCreateValidateCreateData" } - dataDict, err = ValidateCreateData(funcName, manager, ctx, userCred, ownerId, query, dataDict) + dataDict, err = ValidateCreateData(funcName, manager, ctx, userCred, ownerId, query, dataDict) if err != nil { return nil, httperrors.NewGeneralError(err) } @@ -1291,13 +1287,11 @@ func (dispatcher *DBModelDispatcher) Create(ctx context.Context, query jsonutils if len(ctxIds) > 0 { dataDict, ok := data.(*jsonutils.JSONDict) if !ok { - log.Errorf("fail to convert body into jsondict") - return nil, fmt.Errorf("fail to parse body") + return nil, httperrors.NewGeneralError(fmt.Errorf("fail to parse body %s", data)) } data, err = fetchContextObjectsIds(dispatcher.modelManager, ctx, userCred, ctxIds, dataDict) if err != nil { - log.Errorf("fail to find context object %s", ctxIds) - return nil, err + return nil, httperrors.NewGeneralError(errors.Wrapf(err, "fetchContextObjectsIds")) } } @@ -1316,16 +1310,15 @@ func (dispatcher *DBModelDispatcher) Create(ctx context.Context, query jsonutils model, err := DoCreate(dispatcher.modelManager, ctx, userCred, query, data, ownerId) if err != nil { - // log.Errorf("fail to doCreateItem %s", err) if CancelPendingUsagesInContext != nil { - err := CancelPendingUsagesInContext(ctx, userCred) - if err != nil { - log.Errorf("CancelPendingUsagesInContext fail %s", err) + e := CancelPendingUsagesInContext(ctx, userCred) + if e != nil { + err = errors.Wrapf(err, e.Error()) } } failErr := manager.OnCreateFailed(ctx, userCred, ownerId, query, data) if failErr != nil { - log.Errorf("manager.OnCreateFailed %s", failErr) + err = errors.Wrapf(err, failErr.Error()) } return nil, httperrors.NewGeneralError(err) } @@ -1457,9 +1450,9 @@ func (dispatcher *DBModelDispatcher) BatchCreate(ctx context.Context, query json if err != nil { failErr := manager.OnCreateFailed(ctx, userCred, ownerId, query, data) if failErr != nil { - log.Errorf("manager.OnCreateFailed %s", failErr) + err = errors.Wrapf(err, failErr.Error()) } - return nil, errors.Wrap(err, "createResults") + return nil, httperrors.NewGeneralError(errors.Wrap(err, "createResults")) } results := make([]modulebase.SubmitResult, count) @@ -1497,44 +1490,13 @@ func (dispatcher *DBModelDispatcher) BatchCreate(ctx context.Context, query json return results, nil } -func managerPerformCheckCreateData( - manager IModelManager, - ctx context.Context, - userCred mcclient.TokenCredential, - action string, - ownerId mcclient.IIdentityProvider, - query jsonutils.JSONObject, - data jsonutils.JSONObject, -) (jsonutils.JSONObject, error) { - bodyDict := data.(*jsonutils.JSONDict) - - if consts.IsRbacEnabled() { - err := isClassRbacAllowed(manager, userCred, ownerId, policy.PolicyActionPerform, action) - if err != nil { - return nil, err - } - } else if !manager.AllowPerformCheckCreateData(ctx, userCred, query, data) { - return nil, httperrors.NewForbiddenError("not allow to perform %s", action) - } - - if InitPendingUsagesInContext != nil { - ctx = InitPendingUsagesInContext(ctx) - - defer func() { - if CancelPendingUsagesInContext != nil { - err := CancelPendingUsagesInContext(ctx, userCred) - if err != nil { - log.Errorf("CancelPendingUsagesInContext fail %s", err) - } - } - }() - } - - funcName := "ValidateCreateData" - return ValidateCreateData(funcName, manager, ctx, userCred, ownerId, query, bodyDict) -} - func (dispatcher *DBModelDispatcher) PerformClassAction(ctx context.Context, action string, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + if action == "check-create-data" { + dataDict := data.(*jsonutils.JSONDict) + dataDict.Set("dry_run", jsonutils.JSONTrue) + return dispatcher.Create(ctx, query, dataDict, nil) + } + userCred := fetchUserCredential(ctx) manager := dispatcher.modelManager @@ -1546,11 +1508,6 @@ func (dispatcher *DBModelDispatcher) PerformClassAction(ctx context.Context, act lockman.LockClass(ctx, manager, GetLockClassKey(manager, ownerId)) defer lockman.ReleaseClass(ctx, manager, GetLockClassKey(manager, ownerId)) - if action == "check-create-data" { - return managerPerformCheckCreateData(dispatcher.modelManager, - ctx, userCred, action, ownerId, query, data) - } - managerValue := reflect.ValueOf(dispatcher.modelManager) return objectPerformAction(dispatcher, nil, managerValue, ctx, userCred, action, query, data) } @@ -1695,10 +1652,8 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre var err error err = item.ValidateUpdateCondition(ctx) - if err != nil { - log.Errorf("validate update condition error: %s", err) - return nil, httperrors.NewGeneralError(err) + return nil, httperrors.NewGeneralError(errors.Wrapf(err, "ValidateUpdateCondition")) } dataDict, ok := data.(*jsonutils.JSONDict) @@ -1708,9 +1663,7 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre dataDict, err = ValidateUpdateData(item, ctx, userCred, query, dataDict) if err != nil { - errMsg := fmt.Sprintf("validate update data error: %s", err) - log.Errorf(errMsg) - return nil, httperrors.NewGeneralError(err) + return nil, httperrors.NewGeneralError(errors.Wrapf(err, "ValidateUpdateData")) } item.PreUpdate(ctx, userCred, query, dataDict) @@ -1719,16 +1672,12 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre filterData := dataDict.CopyIncludes(updateFields(manager, userCred)...) err = filterData.Unmarshal(item) if err != nil { - errMsg := fmt.Sprintf("unmarshal fail: %s", err) - log.Errorf(errMsg) - return httperrors.NewGeneralError(err) + return httperrors.NewGeneralError(errors.Wrapf(err, "filterData.Unmarshal")) } return nil }) - if err != nil { - log.Errorf("save update error: %s", err) - return nil, httperrors.NewGeneralError(err) + return nil, httperrors.NewGeneralError(errors.Wrapf(err, "Update")) } OpsLog.LogEvent(item, ACT_UPDATE, diff, userCred) logclient.AddActionLogWithContext(ctx, item, logclient.ACT_UPDATE, diff, userCred, true) @@ -1795,15 +1744,12 @@ func objectUpdateSpec(dispatcher *DBModelDispatcher, model IModel, modelValue re } func DeleteModel(ctx context.Context, userCred mcclient.TokenCredential, item IModel) error { - // log.Debugf("Ready to delete %s %s %#v", jsonutils.Marshal(item), item, manager) // cleanModelUsages(ctx, userCred, item) _, err := Update(item, func() error { return item.MarkDelete() }) if err != nil { - msg := fmt.Sprintf("save update error %s", err) - log.Errorf(msg) - return httperrors.NewGeneralError(err) + return httperrors.NewGeneralError(errors.Wrapf(err, "db.Update")) } if userCred != nil { OpsLog.LogEvent(item, ACT_DELETE, item.GetShortDesc(ctx), userCred) @@ -1812,8 +1758,6 @@ func DeleteModel(ctx context.Context, userCred mcclient.TokenCredential, item IM } func deleteItem(manager IModelManager, model IModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { - // log.Debugf("deleteItem %s", jsonutils.Marshal(model)) - err := ValidateDeleteCondition(model, ctx, nil) if err != nil { return nil, err @@ -1821,14 +1765,12 @@ func deleteItem(manager IModelManager, model IModel, ctx context.Context, userCr err = CustomizeDelete(model, ctx, userCred, query, data) if err != nil { - log.Errorf("customize delete error: %s", err) - return nil, httperrors.NewGeneralError(err) + return nil, httperrors.NewGeneralError(errors.Wrapf(err, "CustomizeDelete")) } details, err := getItemDetails(manager, model, ctx, userCred, query) if err != nil { - log.Errorf("fail to get item detail before delete: %s", err) - return nil, httperrors.NewGeneralError(err) + return nil, httperrors.NewGeneralError(errors.Wrapf(err, "getItemDetails")) } model.PreDelete(ctx, userCred) @@ -1836,8 +1778,7 @@ func deleteItem(manager IModelManager, model IModel, ctx context.Context, userCr // err = DeleteModel(ctx, userCred, model) err = model.Delete(ctx, userCred) if err != nil { - log.Errorf("Delete error %s", err) - return nil, err + return nil, errors.Wrapf(err, "Delete") } model.PostDelete(ctx, userCred) @@ -1853,7 +1794,6 @@ func (dispatcher *DBModelDispatcher) Delete(ctx context.Context, idstr string, q } else if err != nil { return nil, httperrors.NewGeneralError(err) } - // log.Debugf("Delete %s", model.GetShortDesc(ctx)) if consts.IsRbacEnabled() { err := isObjectRbacAllowed(model, userCred, policy.PolicyActionDelete) diff --git a/pkg/cloudprovider/instance.go b/pkg/cloudprovider/instance.go index f178e24fb8..39f039f504 100644 --- a/pkg/cloudprovider/instance.go +++ b/pkg/cloudprovider/instance.go @@ -106,6 +106,8 @@ type ServerStopOptions struct { type SManagedVMCreateConfig struct { Name string + NameEn string + Hostname string ExternalImageId string ImageType string OsType string diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 76f20eaa91..02b6ce219c 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -319,6 +319,7 @@ type ICloudVM interface { ConvertPublicIpToEip() error + GetHostname() string GetIHost() ICloudHost GetIHostId() string diff --git a/pkg/cloudprovider/subaccount.go b/pkg/cloudprovider/subaccount.go index c8edfdc7e1..b19fa0a533 100644 --- a/pkg/cloudprovider/subaccount.go +++ b/pkg/cloudprovider/subaccount.go @@ -30,6 +30,7 @@ type SSubAccount struct { DefaultProjectId string // 默认云订阅项目Id } +// +onecloud:model-api-gen type SubAccounts struct { // 若输出则是全量子账号列表,若输入,代表允许同步的子账号 Accounts []SSubAccount diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index d8acfe3c2a..d4db2e6de4 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -41,6 +41,7 @@ import ( "yunion.io/x/onecloud/pkg/util/billing" "yunion.io/x/onecloud/pkg/util/cloudinit" "yunion.io/x/onecloud/pkg/util/logclient" + "yunion.io/x/onecloud/pkg/util/pinyinutils" ) type SManagedVirtualizedGuestDriver struct { @@ -60,6 +61,8 @@ func (d SManagedVirtualizedGuestDriver) DoScheduleCloudproviderTagFilter() bool func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost, params *jsonutils.JSONDict) (jsonutils.JSONObject, error) { config := cloudprovider.SManagedVMCreateConfig{} config.Name = guest.Name + config.NameEn = pinyinutils.Text2Pinyin(guest.Name) + config.Hostname = guest.Hostname config.Cpu = int(guest.VcpuCount) config.MemoryMB = guest.VmemSize config.Description = guest.Description diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index ef0204b033..8cbfa495e2 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -59,6 +59,7 @@ import ( "yunion.io/x/onecloud/pkg/util/billing" "yunion.io/x/onecloud/pkg/util/logclient" "yunion.io/x/onecloud/pkg/util/netutils2" + "yunion.io/x/onecloud/pkg/util/pinyinutils" "yunion.io/x/onecloud/pkg/util/rbacutils" "yunion.io/x/onecloud/pkg/util/seclib2" "yunion.io/x/onecloud/pkg/util/stringutils2" @@ -77,6 +78,7 @@ type SGuestManager struct { SDiskResourceBaseManager SScalingGroupResourceBaseManager db.SMultiArchResourceBaseManager + SHostnameResourceBaseManager } var GuestManager *SGuestManager @@ -90,9 +92,9 @@ func init() { "servers", ), } - log.Infof("init GuestManager") GuestManager.SetVirtualObject(GuestManager) GuestManager.SetAlias("guest", "guests") + GuestManager.NameRequireAscii = false } type SGuest struct { @@ -104,6 +106,7 @@ type SGuest struct { SDeletePreventableResourceBase db.SMultiArchResourceBase + SHostnameResourceBase SHostResourceBase `width:"36" charset:"ascii" nullable:"true" list:"user" get:"user" index:"true"` // CPU大小 @@ -638,6 +641,29 @@ func (manager *SGuestManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field return q, httperrors.ErrNotFound } +func (manager *SGuestManager) initHostname() error { + guests := []SGuest{} + q := manager.Query().IsNullOrEmpty("hostname") + err := db.FetchModelObjects(manager, q, &guests) + if err != nil { + return errors.Wrapf(err, "db.FetchModelObjects") + } + for i := range guests { + db.Update(&guests[i], func() error { + hostname, _ := manager.SHostnameResourceBaseManager.ValidateHostname( + guests[i].Hostname, + guests[i].OsType, + api.HostnameInput{ + Hostname: guests[i].Name, + }, + ) + guests[i].Hostname = hostname.Hostname + return nil + }) + } + return nil +} + func (manager *SGuestManager) InitializeData() error { guests := make([]SGuest, 0, 10) q := manager.Query().Equals("hypervisor", "esxi") @@ -655,7 +681,7 @@ func (manager *SGuestManager) InitializeData() error { return nil }) } - return nil + return manager.initHostname() } func (guest *SGuest) GetHypervisor() string { @@ -1494,6 +1520,10 @@ func (manager *SGuestManager) validateCreateData( if err != nil { return nil, err } + input.HostnameInput, err = manager.SHostnameResourceBaseManager.ValidateHostname(input.Name, input.OsType, input.HostnameInput) + if err != nil { + return nil, err + } if err := userdata.ValidateUserdata(input.UserData); err != nil { return nil, httperrors.NewInputParameterError("Invalid userdata: %v", err) @@ -2481,13 +2511,17 @@ func (self *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.Token extVM.Refresh() if options.NameSyncResources.Contains(self.Keyword()) && !recycle { newName, _ := db.GenerateAlterName(self, extVM.GetName()) - if len(newName) > 0 && newName != self.Name { + if len(newName) > 0 && newName != self.Name && extVM.GetName() != extVM.GetHostname() { self.Name = newName } } + if extVM.GetName() != extVM.GetHostname() { + self.Hostname = extVM.GetHostname() + } if !self.IsFailureStatus() { self.Status = extVM.GetStatus() } + self.VcpuCount = extVM.GetVcpuCount() self.BootOrder = extVM.GetBootOrder() self.Vga = extVM.GetVga() @@ -2584,6 +2618,7 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient. guest.Bios = extVM.GetBios() guest.Machine = extVM.GetMachine() guest.Hypervisor = extVM.GetHypervisor() + guest.Hostname = extVM.GetHostname() guest.IsEmulated = extVM.IsEmulated() @@ -3506,7 +3541,7 @@ func (self *SGuest) createDiskOnStorage(ctx context.Context, userCred mcclient.T lockman.LockClass(ctx, QuotaManager, self.ProjectId) defer lockman.ReleaseClass(ctx, QuotaManager, self.ProjectId) - diskName := fmt.Sprintf("vdisk-%s-%d", self.Name, time.Now().UnixNano()) + diskName := fmt.Sprintf("vdisk-%s-%d", pinyinutils.Text2Pinyin(self.Name), time.Now().UnixNano()) billingType := billing_api.BILLING_TYPE_POSTPAID billingCycle := "" @@ -3957,6 +3992,7 @@ func (self *SGuest) GetIsolatedDevices() ([]SIsolatedDevice, error) { func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *api.GuestJsonDesc { desc := &api.GuestJsonDesc{ Name: self.Name, + Hostname: self.Hostname, Description: self.Description, UUID: self.Id, Mem: self.VmemSize, @@ -5577,13 +5613,6 @@ var ( hostnameREG = regexp.MustCompile(`^[a-z$][a-z0-9-${}.]*$`) ) -func (manager *SGuestManager) ValidateName(name string) error { - if serverNameREG.MatchString(name) { - return nil - } - return httperrors.NewInputParameterError("name starts with letter, and contains letter, number and - only") -} - func (manager *SGuestManager) ValidateNameLoginAccount(name string) error { if hostnameREG.MatchString(name) { return nil diff --git a/pkg/compute/models/hostnameresource.go b/pkg/compute/models/hostnameresource.go new file mode 100644 index 0000000000..ff67164b46 --- /dev/null +++ b/pkg/compute/models/hostnameresource.go @@ -0,0 +1,75 @@ +// 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 models + +import ( + "strconv" + "strings" + + "yunion.io/x/pkg/util/osprofile" + + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/util/pinyinutils" +) + +type SHostnameResourceBase struct { + Hostname string `width:"60" charset:"ascii" nullable:"true" list:"user" create:"optional"` +} + +type SHostnameResourceBaseManager struct { +} + +func (manager *SHostnameResourceBaseManager) ValidateHostname(name string, osType string, input api.HostnameInput) (api.HostnameInput, error) { + if len(input.Hostname) == 0 { + if len(name) == 0 { + return input, httperrors.NewMissingParameterError("name") + } + input.Hostname = pinyinutils.Text2Pinyin(name) + } + hostname := "" + for _, s := range input.Hostname { + if (s >= '0' && s <= '9') || (s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || strings.Contains(".-", string(s)) { + hostname += string(s) + } + } + input.Hostname = hostname + for strings.HasPrefix(input.Hostname, ".") || strings.HasPrefix(input.Hostname, "-") || + strings.HasSuffix(input.Hostname, ".") || strings.HasSuffix(input.Hostname, "-") || + strings.Contains(input.Hostname, "..") || strings.Contains(input.Hostname, "--") { + input.Hostname = strings.TrimPrefix(input.Hostname, ".") + input.Hostname = strings.TrimPrefix(input.Hostname, "-") + input.Hostname = strings.TrimSuffix(input.Hostname, ".") + input.Hostname = strings.TrimSuffix(input.Hostname, "-") + input.Hostname = strings.ReplaceAll(input.Hostname, "--", "") + input.Hostname = strings.ReplaceAll(input.Hostname, "..", "") + } + if len(input.Hostname) > 60 { + input.Hostname = input.Hostname[:60] + } + if strings.ToLower(osType) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) { + if num, err := strconv.Atoi(input.Hostname); err == nil && num > 0 { + return input, httperrors.NewInputParameterError("hostname cannot be number %d", num) + } + input.Hostname = strings.ReplaceAll(input.Hostname, ".", "") + if len(input.Hostname) > 15 { + input.Hostname = input.Hostname[:15] + } + } + if len(input.Hostname) < 2 { + return input, httperrors.NewInputParameterError("the hostname length must be greater than or equal to 2") + } + return input, nil +} diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index c115524321..84bf77c644 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -63,9 +63,9 @@ import ( type SHostManager struct { db.SEnabledStatusInfrasResourceBaseManager db.SExternalizedResourceBaseManager - db.SHostNameValidatorManager SZoneResourceBaseManager SManagedResourceBaseManager + SHostnameResourceBaseManager } var HostManager *SHostManager @@ -81,6 +81,7 @@ func init() { } HostManager.SetVirtualObject(HostManager) HostManager.SetAlias("baremetal", "baremetals") + GuestManager.NameRequireAscii = false } type SHost struct { @@ -89,6 +90,7 @@ type SHost struct { SZoneResourceBase `update:""` SManagedResourceBase SBillingResourceBase + SHostnameResourceBase // 机架 Rack string `width:"16" charset:"ascii" nullable:"true" get:"domain" update:"domain" create:"domain_optional"` @@ -3461,6 +3463,10 @@ func (manager *SHostManager) ValidateCreateData( if err != nil { return input, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ValidateCreateData") } + input.HostnameInput, err = manager.SHostnameResourceBaseManager.ValidateHostname(input.Name, "", input.HostnameInput) + if err != nil { + return input, err + } keys := GetHostQuotaKeysFromCreateInput(ownerId, input) quota := SInfrasQuota{Host: 1} @@ -6035,3 +6041,30 @@ func (host *SHost) IsAssignable(userCred mcclient.TokenCredential) error { return httperrors.NewNotSufficientPrivilegeError("Only system admin can assign host") } } + +func (manager *SHostManager) initHostname() error { + hosts := []SHost{} + q := manager.Query().IsNullOrEmpty("hostname") + err := db.FetchModelObjects(manager, q, &hosts) + if err != nil { + return errors.Wrapf(err, "db.FetchModelObjects") + } + for i := range hosts { + db.Update(&hosts[i], func() error { + hostname, _ := manager.SHostnameResourceBaseManager.ValidateHostname( + hosts[i].Hostname, + "", + api.HostnameInput{ + Hostname: hosts[i].Name, + }, + ) + hosts[i].Hostname = hostname.Hostname + return nil + }) + } + return nil +} + +func (manager *SHostManager) InitializeData() error { + return manager.initHostname() +} diff --git a/pkg/compute/models/initdb.go b/pkg/compute/models/initdb.go index 11e9b15b32..3ad853dd0b 100644 --- a/pkg/compute/models/initdb.go +++ b/pkg/compute/models/initdb.go @@ -44,6 +44,7 @@ func InitDB() error { NetworkManager, NetworkAddressManager, GuestManager, + HostManager, LoadbalancerCertificateManager, LoadbalancerAclManager, LoadbalancerManager, diff --git a/pkg/hostman/hostinfo/hostdhcp/dhcpserver.go b/pkg/hostman/hostinfo/hostdhcp/dhcpserver.go index e7704b3428..f7581b8262 100644 --- a/pkg/hostman/hostinfo/hostdhcp/dhcpserver.go +++ b/pkg/hostman/hostinfo/hostdhcp/dhcpserver.go @@ -105,7 +105,7 @@ func (s *SGuestDHCPServer) getGuestConfig(guestDesc, guestNic jsonutils.JSONObje conf.ServerIP = net.ParseIP(v4Ip.NetAddr(int8(masklen)).String()) conf.SubnetMask = net.ParseIP(netutils2.Netlen2Mask(int(masklen))) conf.BroadcastAddr = v4Ip.BroadcastAddr(int8(masklen)).ToBytes() - conf.Hostname, _ = guestDesc.GetString("name") + conf.Hostname, _ = guestDesc.GetString("hostname") conf.Domain = nicdesc.Domain // get main ip diff --git a/pkg/multicloud/aliyun/host.go b/pkg/multicloud/aliyun/host.go index 1ea5b2ad7c..e743f920ad 100644 --- a/pkg/multicloud/aliyun/host.go +++ b/pkg/multicloud/aliyun/host.go @@ -176,7 +176,7 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { } func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, + vmId, err := self._createVM(desc.Name, desc.Hostname, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle, desc.ProjectId, desc.OsType, desc.Tags, desc.SPublicIpInfo) @@ -190,7 +190,7 @@ func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr return vm, nil } -func (self *SHost) _createVM(name string, imgId string, +func (self *SHost) _createVM(name, hostname string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, vswitchId string, ipAddr string, desc string, passwd string, dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupId string, @@ -251,7 +251,7 @@ func (self *SHost) _createVM(name string, imgId string, if len(instanceType) > 0 { log.Debugf("Try instancetype : %s", instanceType) - vmId, err := self.zone.region.CreateInstance(name, imgId, instanceType, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp) + vmId, err := self.zone.region.CreateInstance(name, hostname, imgId, instanceType, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp) if err != nil { log.Errorf("Failed for %s: %s", instanceType, err) return "", fmt.Errorf("Failed to create specification %s.%s", instanceType, err.Error()) @@ -271,7 +271,7 @@ func (self *SHost) _createVM(name string, imgId string, for _, instType := range instanceTypes { instanceTypeId := instType.InstanceTypeId log.Debugf("Try instancetype : %s", instanceTypeId) - vmId, err = self.zone.region.CreateInstance(name, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp) + vmId, err = self.zone.region.CreateInstance(name, hostname, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp) if err != nil { log.Errorf("Failed for %s: %s", instanceTypeId, err) } else { diff --git a/pkg/multicloud/aliyun/instance.go b/pkg/multicloud/aliyun/instance.go index 2dbcc176cf..c59d268a4a 100644 --- a/pkg/multicloud/aliyun/instance.go +++ b/pkg/multicloud/aliyun/instance.go @@ -33,7 +33,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/multicloud" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/onecloud/pkg/util/stringutils2" ) const ( @@ -191,6 +190,10 @@ func (self *SInstance) GetName() string { if len(self.InstanceName) > 0 { return self.InstanceName } + return self.InstanceId +} + +func (self *SInstance) GetHostname() string { return self.HostName } @@ -532,7 +535,7 @@ func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) { return &instances[0], nil } -func (self *SRegion) CreateInstance(name string, imageId string, instanceType string, securityGroupId string, +func (self *SRegion) CreateInstance(name, hostname string, imageId string, instanceType string, securityGroupId string, zoneId string, desc string, passwd string, disks []SDisk, vSwitchId string, ipAddr string, keypair string, userData string, bc *billing.SBillingCycle, projectId, osType string, tags map[string]string, publicIp cloudprovider.SPublicIpInfo, @@ -544,6 +547,9 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st params["SecurityGroupId"] = securityGroupId params["ZoneId"] = zoneId params["InstanceName"] = name + if len(hostname) > 0 { + params["HostName"] = hostname + } params["Description"] = desc params["InternetChargeType"] = "PayByTraffic" params["InternetMaxBandwidthIn"] = "200" @@ -554,7 +560,6 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st if publicIp.PublicIpChargeType == cloudprovider.ElasticipChargeTypeByBandwidth { params["InternetChargeType"] = "PayByBandwidth" } - params["HostName"] = stringutils2.GenerateHostName(name, osType) if len(passwd) > 0 { params["Password"] = passwd } else { @@ -797,7 +802,6 @@ func (self *SRegion) DeployVM(instanceId string, name string, password string, k if len(name) > 0 && instance.InstanceName != name { params["InstanceName"] = name - params["HostName"] = stringutils2.GenerateHostName(name, instance.OSType) } if len(description) > 0 && instance.Description != description { @@ -835,7 +839,6 @@ func (self *SRegion) UpdateVM(instanceId string, name, osType string) error { https://help.aliyun.com/document_detail/25503.html?spm=a2c4g.11186623.4.1.DrgpjW */ params := make(map[string]string) - params["HostName"] = stringutils2.GenerateHostName(name, osType) params["InstanceName"] = name return self.modifyInstanceAttribute(instanceId, params) } diff --git a/pkg/multicloud/apsara/host.go b/pkg/multicloud/apsara/host.go index 512cc04fff..a1d25778bf 100644 --- a/pkg/multicloud/apsara/host.go +++ b/pkg/multicloud/apsara/host.go @@ -175,7 +175,7 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { } func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, + vmId, err := self._createVM(desc.Name, desc.Hostname, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle, desc.ProjectId, desc.OsType, desc.Tags) @@ -190,7 +190,7 @@ func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr return vm, err } -func (self *SHost) _createVM(name string, imgId string, +func (self *SHost) _createVM(name, hostname string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, vswitchId string, ipAddr string, desc string, passwd string, dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupId string, @@ -251,7 +251,7 @@ func (self *SHost) _createVM(name string, imgId string, if len(instanceType) > 0 { log.Debugf("Try instancetype : %s", instanceType) - vmId, err := self.zone.region.CreateInstance(name, imgId, instanceType, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags) + vmId, err := self.zone.region.CreateInstance(name, hostname, imgId, instanceType, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags) if err != nil { log.Errorf("Failed for %s: %s", instanceType, err) return "", fmt.Errorf("Failed to create specification %s.%s", instanceType, err.Error()) @@ -271,7 +271,7 @@ func (self *SHost) _createVM(name string, imgId string, for _, instType := range instanceTypes { instanceTypeId := instType.InstanceTypeId log.Debugf("Try instancetype : %s", instanceTypeId) - vmId, err = self.zone.region.CreateInstance(name, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags) + vmId, err = self.zone.region.CreateInstance(name, hostname, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags) if err != nil { log.Errorf("Failed for %s: %s", instanceTypeId, err) } else { diff --git a/pkg/multicloud/apsara/instance.go b/pkg/multicloud/apsara/instance.go index bc86585da5..d78d035bc3 100644 --- a/pkg/multicloud/apsara/instance.go +++ b/pkg/multicloud/apsara/instance.go @@ -32,7 +32,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/multicloud" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/onecloud/pkg/util/stringutils2" ) const ( @@ -183,6 +182,10 @@ func (self *SInstance) GetName() string { if len(self.InstanceName) > 0 { return self.InstanceName } + return self.InstanceId +} + +func (self *SInstance) GetHostname() string { return self.HostName } @@ -478,7 +481,7 @@ func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) { return &instances[0], nil } -func (self *SRegion) CreateInstance(name string, imageId string, instanceType string, securityGroupId string, +func (self *SRegion) CreateInstance(name, hostname string, imageId string, instanceType string, securityGroupId string, zoneId string, desc string, passwd string, disks []SDisk, vSwitchId string, ipAddr string, keypair string, userData string, bc *billing.SBillingCycle, projectId, osType string, tags map[string]string, @@ -490,11 +493,13 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st params["SecurityGroupId"] = securityGroupId params["ZoneId"] = zoneId params["InstanceName"] = name + if len(hostname) > 0 { + params["HostName"] = hostname + } params["Description"] = desc params["InternetChargeType"] = "PayByTraffic" params["InternetMaxBandwidthIn"] = "200" params["InternetMaxBandwidthOut"] = "100" - params["HostName"] = stringutils2.GenerateHostName(name, osType) if len(passwd) > 0 { params["Password"] = passwd } else { @@ -719,7 +724,6 @@ func (self *SRegion) DeployVM(instanceId string, name string, password string, k if len(name) > 0 && instance.InstanceName != name { params["InstanceName"] = name - params["HostName"] = stringutils2.GenerateHostName(name, instance.OSType) } if len(description) > 0 && instance.Description != description { @@ -757,7 +761,6 @@ func (self *SRegion) UpdateVM(instanceId string, name, osType string) error { https://help.apsara.com/document_detail/25503.html?spm=a2c4g.11186623.4.1.DrgpjW */ params := make(map[string]string) - params["HostName"] = stringutils2.GenerateHostName(name, osType) params["InstanceName"] = name return self.modifyInstanceAttribute(instanceId, params) } diff --git a/pkg/multicloud/aws/instance.go b/pkg/multicloud/aws/instance.go index 91a17feb28..cd14c75d11 100644 --- a/pkg/multicloud/aws/instance.go +++ b/pkg/multicloud/aws/instance.go @@ -173,6 +173,10 @@ func (self *SInstance) GetName() string { return self.GetId() } +func (self *SInstance) GetHostname() string { + return self.GetName() +} + func (self *SInstance) GetGlobalId() string { return self.InstanceId } diff --git a/pkg/multicloud/azure/classic_instance.go b/pkg/multicloud/azure/classic_instance.go index 94b7083cb8..5b51b7a1a1 100644 --- a/pkg/multicloud/azure/classic_instance.go +++ b/pkg/multicloud/azure/classic_instance.go @@ -307,6 +307,10 @@ func (self *SClassicInstance) GetName() string { return self.Name } +func (self *SClassicInstance) GetHostname() string { + return self.Name +} + func (self *SClassicInstance) GetGlobalId() string { return strings.ToLower(self.ID) } diff --git a/pkg/multicloud/azure/host.go b/pkg/multicloud/azure/host.go index 7921cd0a70..65f3ff903f 100644 --- a/pkg/multicloud/azure/host.go +++ b/pkg/multicloud/azure/host.go @@ -61,7 +61,7 @@ func (self *SHost) Refresh() error { } func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { - nic, err := self.zone.region.CreateNetworkInterface(desc.ProjectId, fmt.Sprintf("%s-ipconfig", desc.Name), desc.IpAddr, desc.ExternalNetworkId, desc.ExternalSecgroupId) + nic, err := self.zone.region.CreateNetworkInterface(desc.ProjectId, fmt.Sprintf("%s-ipconfig", desc.NameEn), desc.IpAddr, desc.ExternalNetworkId, desc.ExternalSecgroupId) if err != nil { return nil, errors.Wrapf(err, "CreateNetworkInterface") } @@ -92,7 +92,7 @@ func (self *SRegion) _createVM(desc *cloudprovider.SManagedVMCreateConfig, nicId if !utils.IsInStringArray(desc.OsType, []string{osprofile.OS_TYPE_LINUX, osprofile.OS_TYPE_WINDOWS}) { desc.OsType = string(image.GetOsType()) } - computeName := desc.Name + computeName := desc.Hostname for _, k := range "`~!@#$%^&*()=+_[]{}\\|;:.'\",<>/?" { computeName = strings.Replace(computeName, string(k), "", -1) } @@ -108,7 +108,7 @@ func (self *SRegion) _createVM(desc *cloudprovider.SManagedVMCreateConfig, nicId osProfile["CustomData"] = desc.UserData } params := jsonutils.Marshal(map[string]interface{}{ - "Name": desc.Name, + "Name": desc.NameEn, "Location": self.Name, "Properties": map[string]interface{}{ "HardwareProfile": map[string]string{ diff --git a/pkg/multicloud/azure/instance.go b/pkg/multicloud/azure/instance.go index 90e5f35a0d..bbd6ae9d6a 100644 --- a/pkg/multicloud/azure/instance.go +++ b/pkg/multicloud/azure/instance.go @@ -786,6 +786,10 @@ func (self *SInstance) GetName() string { return self.Name } +func (self *SInstance) GetHostname() string { + return self.Name +} + func (self *SInstance) GetGlobalId() string { return strings.ToLower(self.ID) } diff --git a/pkg/multicloud/cloudpods/instance.go b/pkg/multicloud/cloudpods/instance.go index f4f1fcf9b8..80368997ab 100644 --- a/pkg/multicloud/cloudpods/instance.go +++ b/pkg/multicloud/cloudpods/instance.go @@ -45,6 +45,10 @@ func (self *SInstance) GetName() string { return self.Name } +func (self *SInstance) GetHostname() string { + return self.Hostname +} + func (self *SInstance) GetId() string { return self.Id } @@ -420,6 +424,7 @@ func (self *SRegion) CreateInstance(hostId, hypervisor string, opts *cloudprovid ServerConfigs: &api.ServerConfigs{}, } input.Name = opts.Name + input.Hostname = opts.Hostname input.Description = opts.Description input.InstanceType = opts.InstanceType input.VcpuCount = opts.Cpu diff --git a/pkg/multicloud/ctyun/instance.go b/pkg/multicloud/ctyun/instance.go index a38df8de9d..70a59fa9c4 100644 --- a/pkg/multicloud/ctyun/instance.go +++ b/pkg/multicloud/ctyun/instance.go @@ -133,6 +133,10 @@ func (self *SInstance) GetName() string { return self.Name } +func (self *SInstance) GetHostname() string { + return self.Name +} + func (self *SInstance) GetGlobalId() string { return self.GetId() } diff --git a/pkg/multicloud/ecloud/instance.go b/pkg/multicloud/ecloud/instance.go index 05fa9bc57e..2c91a591cc 100644 --- a/pkg/multicloud/ecloud/instance.go +++ b/pkg/multicloud/ecloud/instance.go @@ -97,6 +97,10 @@ func (i *SInstance) GetName() string { return i.Name } +func (i *SInstance) GetHostname() string { + return i.Name +} + func (i *SInstance) GetGlobalId() string { return i.GetId() } diff --git a/pkg/multicloud/esxi/virtualmachine.go b/pkg/multicloud/esxi/virtualmachine.go index 0dd1e57fe4..8bfa4fa723 100644 --- a/pkg/multicloud/esxi/virtualmachine.go +++ b/pkg/multicloud/esxi/virtualmachine.go @@ -140,6 +140,10 @@ func (self *SVirtualMachine) GetGlobalId() string { return self.getUuid() } +func (self *SVirtualMachine) GetHostname() string { + return self.GetName() +} + func (self *SVirtualMachine) GetStatus() string { // err := self.CheckFileInfo(context.Background()) // if err != nil { diff --git a/pkg/multicloud/google/instance.go b/pkg/multicloud/google/instance.go index 44a2053f92..71d7ce8f18 100644 --- a/pkg/multicloud/google/instance.go +++ b/pkg/multicloud/google/instance.go @@ -129,8 +129,8 @@ func (region *SRegion) GetInstance(id string) (*SInstance, error) { return instance, region.Get(id, instance) } -func (instnace *SInstance) IsEmulated() bool { - return false +func (instance *SInstance) GetHostname() string { + return instance.GetName() } func (instance *SInstance) fetchMachineType() error { @@ -660,7 +660,7 @@ func (region *SRegion) _createVM(zone string, desc *cloudprovider.SManagedVMCrea networkInterface["networkIp"] = desc.IpAddr } params := map[string]interface{}{ - "name": desc.Name, + "name": desc.NameEn, "description": desc.Description, "machineType": fmt.Sprintf("zones/%s/machineTypes/%s", zone, desc.InstanceType), "networkInterfaces": []map[string]string{ diff --git a/pkg/multicloud/hcso/instance.go b/pkg/multicloud/hcso/instance.go index 8a6f8f1001..ecaf9a13dc 100644 --- a/pkg/multicloud/hcso/instance.go +++ b/pkg/multicloud/hcso/instance.go @@ -203,6 +203,10 @@ func (self *SInstance) GetName() string { return self.Name } +func (self *SInstance) GetHostname() string { + return self.OSEXTSRVATTRHostname +} + func (self *SInstance) GetGlobalId() string { return self.ID } diff --git a/pkg/multicloud/huawei/instance.go b/pkg/multicloud/huawei/instance.go index 02634ed564..fb06ada40e 100644 --- a/pkg/multicloud/huawei/instance.go +++ b/pkg/multicloud/huawei/instance.go @@ -200,6 +200,10 @@ func (self *SInstance) GetId() string { return self.ID } +func (self *SInstance) GetHostname() string { + return self.OSEXTSRVATTRHostname +} + func (self *SInstance) GetName() string { return self.Name } diff --git a/pkg/multicloud/jdcloud/instance.go b/pkg/multicloud/jdcloud/instance.go index b75ca3e37a..272a6cadf0 100644 --- a/pkg/multicloud/jdcloud/instance.go +++ b/pkg/multicloud/jdcloud/instance.go @@ -63,6 +63,10 @@ func (i *SInstance) GetName() string { return i.InstanceName } +func (i *SInstance) GetHostname() string { + return i.Hostname +} + func (i *SInstance) GetGlobalId() string { return i.GetId() } diff --git a/pkg/multicloud/openstack/instance.go b/pkg/multicloud/openstack/instance.go index b0a424d4a3..e72847e888 100644 --- a/pkg/multicloud/openstack/instance.go +++ b/pkg/multicloud/openstack/instance.go @@ -223,6 +223,10 @@ func (instance *SInstance) GetName() string { return instance.Name } +func (instance *SInstance) GetHostname() string { + return instance.Hostname +} + func (instance *SInstance) GetGlobalId() string { return instance.Id } diff --git a/pkg/multicloud/qcloud/host.go b/pkg/multicloud/qcloud/host.go index 22583e12e3..d406840cbd 100644 --- a/pkg/multicloud/qcloud/host.go +++ b/pkg/multicloud/qcloud/host.go @@ -55,7 +55,7 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) { } func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { - vmId, err := self._createVM(desc.Name, desc.ExternalImageId, + vmId, err := self._createVM(desc.Name, desc.Hostname, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, @@ -71,7 +71,7 @@ func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr return vm, err } -func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, +func (self *SHost) _createVM(name, hostname string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string, networkId string, ipAddr string, desc string, passwd string, diskSizes []cloudprovider.SDiskInfo, publicKey string, secgroupId string, userData string, bc *billing.SBillingCycle, projectId string, publicIpBw int, publicIpChargeType cloudprovider.TElasticipChargeType, @@ -126,7 +126,7 @@ func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SD if len(instanceType) > 0 { log.Debugf("Try instancetype : %s", instanceType) - vmId, err := self.zone.region.CreateInstance(name, imgId, instanceType, secgroupId, self.zone.Zone, desc, passwd, disks, networkId, ipAddr, keypair, userData, bc, projectId, publicIpBw, publicIpChargeType, tags, osType) + vmId, err := self.zone.region.CreateInstance(name, hostname, imgId, instanceType, secgroupId, self.zone.Zone, desc, passwd, disks, networkId, ipAddr, keypair, userData, bc, projectId, publicIpBw, publicIpChargeType, tags, osType) if err != nil { return "", errors.Wrapf(err, "Failed to create specification %s", instanceType) } @@ -145,7 +145,7 @@ func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SD for _, instType := range instanceTypes { instanceTypeId := instType.InstanceType log.Debugf("Try instancetype : %s", instanceTypeId) - vmId, err = self.zone.region.CreateInstance(name, imgId, instanceTypeId, secgroupId, self.zone.Zone, desc, passwd, disks, networkId, ipAddr, keypair, userData, bc, projectId, publicIpBw, publicIpChargeType, tags, osType) + vmId, err = self.zone.region.CreateInstance(name, hostname, imgId, instanceTypeId, secgroupId, self.zone.Zone, desc, passwd, disks, networkId, ipAddr, keypair, userData, bc, projectId, publicIpBw, publicIpChargeType, tags, osType) if err != nil { log.Errorf("Failed for %s: %s", instanceTypeId, err) } else { diff --git a/pkg/multicloud/qcloud/instance.go b/pkg/multicloud/qcloud/instance.go index 7c08c561a4..d8267801fe 100644 --- a/pkg/multicloud/qcloud/instance.go +++ b/pkg/multicloud/qcloud/instance.go @@ -35,7 +35,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/multicloud" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/onecloud/pkg/util/stringutils2" ) const ( @@ -195,6 +194,10 @@ func (self *SInstance) GetName() string { return self.InstanceId } +func (self *SInstance) GetHostname() string { + return self.GetName() +} + func (self *SInstance) GetGlobalId() string { return self.InstanceId } @@ -537,7 +540,7 @@ func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) { return &instances[0], nil } -func (self *SRegion) CreateInstance(name string, imageId string, instanceType string, securityGroupId string, +func (self *SRegion) CreateInstance(name, hostname string, imageId string, instanceType string, securityGroupId string, zoneId string, desc string, passwd string, disks []SDisk, networkId string, ipAddr string, keypair string, userData string, bc *billing.SBillingCycle, projectId string, publicIpBw int, publicIpChargeType cloudprovider.TElasticipChargeType, @@ -553,7 +556,9 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st params["Placement.ProjectId"] = projectId } params["InstanceName"] = name - params["HostName"] = stringutils2.GenerateHostName(name, osType) + if len(hostname) > 0 { + params["HostName"] = hostname + } bandwidth := publicIpBw if publicIpBw == 0 { diff --git a/pkg/multicloud/ucloud/instance.go b/pkg/multicloud/ucloud/instance.go index 8a8d4a84bc..b6d88c1d43 100644 --- a/pkg/multicloud/ucloud/instance.go +++ b/pkg/multicloud/ucloud/instance.go @@ -132,10 +132,13 @@ func (self *SInstance) GetName() string { if len(self.Name) == 0 { return self.GetId() } - return self.Name } +func (self *SInstance) GetHostname() string { + return self.GetName() +} + func (self *SInstance) GetGlobalId() string { return self.GetId() } diff --git a/pkg/multicloud/zstack/instance.go b/pkg/multicloud/zstack/instance.go index 953d2adab2..95670e992f 100644 --- a/pkg/multicloud/zstack/instance.go +++ b/pkg/multicloud/zstack/instance.go @@ -128,6 +128,10 @@ func (instance *SInstance) GetName() string { return instance.Name } +func (instance *SInstance) GetHostname() string { + return instance.Name +} + func (instance *SInstance) GetGlobalId() string { return instance.GetId() } diff --git a/pkg/util/stringutils2/stringutils.go b/pkg/util/stringutils2/stringutils.go index b6bdb86b8c..ad386b02a9 100644 --- a/pkg/util/stringutils2/stringutils.go +++ b/pkg/util/stringutils2/stringutils.go @@ -19,12 +19,8 @@ import ( "encoding/hex" "fmt" "math/rand" - "strconv" "strings" "time" - "unicode" - - "yunion.io/x/pkg/util/osprofile" ) func GetMD5Hash(text string) string { @@ -127,67 +123,6 @@ func SplitByQuotation(line string) ([]string, error) { return segs, nil } -func GenerateHostName(name string, osType string) string { - if len(name) < 2 { - name = fmt.Sprintf("hostname-for-%s-%s", name, osType) - } - // ()英文句号(.)和短横线(-)不能作为首尾字符,更不能连续使用。 - // 点号(.)和短横线(-)不能作为 HostName 的首尾字符,不能连续使用。 - var init = func(s string) string { - for { - if strings.Contains(s, "..") || strings.Contains(s, "--") { - s = strings.ReplaceAll(s, "..", ".") - s = strings.ReplaceAll(s, "--", "-") - continue - } - if strings.HasPrefix(s, ".") || strings.HasPrefix(s, "-") { - s = strings.TrimPrefix(s, ".") - s = strings.TrimPrefix(s, "-") - continue - } - if strings.HasSuffix(s, ".") || strings.HasSuffix(s, "-") { - s = strings.TrimSuffix(s, ".") - s = strings.TrimSuffix(s, "-") - continue - } - break - } - return s - } - name = init(name) - // (阿里云)Windows实例:字符长度为2~15,不支持英文句号(.),不能全是数字。允许大小写英文字母、数字和短横线(-)。 - // (腾讯云)Windows 实例:名字符长度为[2, 15],允许字母(不限制大小写)、数字和短横线(-)组成,不支持点号(.),不能全是数字 - var forWindows = func(s string) string { - s = strings.ReplaceAll(s, ".", "") - ret := "" - for _, c := range s { - if unicode.IsLetter(c) || unicode.IsNumber(c) || c == '-' { - ret += string(c) - } - } - _, err := strconv.Atoi(ret) - if err == nil { - ret = "host-" + ret - } - if len(ret) > 15 { - ret = init(ret[:15]) - } - return ret - } - // (阿里云)其他类型实例(Linux等):字符长度为2~64,支持多个英文句号(.),英文句号之间为一段,每段允许大小写英文字母、数字和短横线(-)。 - // (腾讯云)其他类型(Linux 等)实例:字符长度为[2, 60],允许支持多个点号,点之间为一段,每段允许字母(不限制大小写)、数字和短横线(-)组成。 - var forOther = func(s string) string { - if len(s) > 60 { - return init(s[:60]) - } - return s - } - if strings.ToLower(osType) == strings.ToLower(osprofile.OS_TYPE_WINDOWS) { - return forWindows(name) - } - return forOther(name) -} - func GetCharTypeCount(str string) int { digitIdx := 0 lowerIdx := 1 diff --git a/pkg/util/stringutils2/stringutils_test.go b/pkg/util/stringutils2/stringutils_test.go index bd5c1c926d..d560b6e516 100644 --- a/pkg/util/stringutils2/stringutils_test.go +++ b/pkg/util/stringutils2/stringutils_test.go @@ -17,8 +17,6 @@ package stringutils2 import ( "reflect" "testing" - - "yunion.io/x/pkg/util/osprofile" ) func TestEscapeString(t *testing.T) { @@ -123,50 +121,6 @@ func TestEscapeEchoString(t *testing.T) { } } -func TestGenerateHostName(t *testing.T) { - type input struct { - name string - osType string - hostName string - } - for _, pair := range []input{ - input{ - name: "--test-host-name.......", - hostName: "test-host-name", - }, - input{ - name: "--test-host-1234567890-name.......", - osType: osprofile.OS_TYPE_WINDOWS, - hostName: "test-host-12345", - }, - input{ - name: "--test-host-1234-67890-name.......", - osType: osprofile.OS_TYPE_WINDOWS, - hostName: "test-host-1234", - }, - input{ - name: "1234567890123456", - osType: osprofile.OS_TYPE_WINDOWS, - hostName: "host-1234567890", - }, - input{ - name: "001234567890123456", - osType: osprofile.OS_TYPE_WINDOWS, - hostName: "host-0012345678", - }, - - input{ - name: "", - hostName: "hostname-for", - }, - } { - hostName := GenerateHostName(pair.name, pair.osType) - if hostName != pair.hostName { - t.Fatalf("%s hostName should be %s, current is %s", pair.name, pair.hostName, hostName) - } - } -} - func TestGetCharTypeCount(t *testing.T) { cases := []struct { in string