| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- // 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 cloudprovider
- import (
- "encoding/base64"
- "strings"
- "yunion.io/x/jsonutils"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/billing"
- "yunion.io/x/pkg/util/cloudinit"
- "yunion.io/x/pkg/util/osprofile"
- "yunion.io/x/pkg/util/seclib"
- "yunion.io/x/cloudmux/pkg/apis"
- )
- type TOsType string
- var (
- OsTypeLinux = TOsType(osprofile.OS_TYPE_LINUX)
- OsTypeWindows = TOsType(osprofile.OS_TYPE_WINDOWS)
- )
- type TBiosType string
- var (
- BIOS = TBiosType("BIOS")
- UEFI = TBiosType("UEFI")
- )
- func ToBiosType(bios string) TBiosType {
- switch strings.ToLower(bios) {
- case "uefi", "efi":
- return UEFI
- default:
- return BIOS
- }
- }
- type SDistDefaultAccount struct {
- // 操作系统发行版
- OsDistribution string
- // 默认用户名
- DefaultAccount string
- // 是否可更改
- Changeable bool
- }
- type SOsDefaultAccount struct {
- // 默认用户名
- DefaultAccount string
- // 是否可更改用户名
- Changeable bool
- // 禁止使用的账号
- DisabledAccounts []string
- // 各操作系统发行版的默认用户名信息
- DistAccounts []SDistDefaultAccount
- }
- type SDefaultAccount struct {
- Linux SOsDefaultAccount
- Windows SOsDefaultAccount
- }
- type StorageInfo struct {
- StorageType string
- MaxSizeGb int
- MinSizeGb int
- Resizable bool
- StepSizeGb int
- }
- type Storage struct {
- DataDisk []StorageInfo
- SysDisk []StorageInfo
- }
- type SInstanceCapability struct {
- Provider string
- Hypervisor string
- Storages Storage
- DefaultAccount SDefaultAccount
- }
- type SDiskInfo struct {
- StorageExternalId string
- StorageType string
- SizeGB int
- Iops int
- Driver string
- CacheMode string
- Name string
- // aws gp3 only
- Throughput int
- }
- type GuestDiskCreateOptions struct {
- SizeMb int
- UUID string
- Driver string
- Idx int
- StorageId string
- Preallocation string `choices:"off|metadata|full|falloc"`
- }
- const (
- CLOUD_SHELL = "cloud-shell"
- CLOUD_SHELL_WITHOUT_ENCRYPT = "cloud-shell-without-encrypt"
- CLOUD_CONFIG = "cloud-config"
- CLOUD_POWER_SHELL = "powershell"
- CLOUD_EC2 = "ec2"
- )
- type SPublicIpInfo struct {
- PublicIpBw int
- PublicIpChargeType TElasticipChargeType
- }
- type ServerStopOptions struct {
- IsForce bool
- StopCharging bool
- }
- type SManagedVMCreateConfig struct {
- Name string
- NameEn string
- Hostname string
- ExternalImageId string
- ImageType string
- OsType string
- OsDistribution string
- OsVersion string
- InstanceType string // InstanceType 不为空时,直接采用InstanceType创建机器。
- Cpu int
- MemoryMB int
- ExternalNetworkId string
- ExternalVpcId string
- IpAddr string
- Description string
- SysDisk SDiskInfo
- DataDisks []SDiskInfo
- KeypairName string
- PublicKey string
- ExternalSecgroupIds []string
- Account string
- Password string
- UserData string
- ProjectId string
- EnableMonitorAgent bool
- // 金山云按量付费类型
- // Daily(按量付费(按日月结))、 HourlyInstantSettlement(按量付费(按小时月结))
- KsyunPostpaidChargeType string
- SPublicIpInfo
- Tags map[string]string
- BillingCycle *billing.SBillingCycle
- IsNeedInjectPasswordByCloudInit bool
- UserDataType string
- WindowsUserDataType string
- IsWindowsUserDataTypeNeedEncode bool
- IsolateDevices []SIsolateDevice
- }
- type SIsolateDevice struct {
- Id string
- Name string
- }
- type SManagedVMChangeConfig struct {
- Cpu int
- CpuSocket int
- MemoryMB int
- InstanceType string
- }
- type SManagedVMRebuildRootConfig struct {
- Account string
- Password string
- ImageId string
- KeypairName string
- PublicKey string
- SysSizeGB int
- OsType string
- UserData string
- }
- func (vmConfig *SManagedVMCreateConfig) GetConfig(config *jsonutils.JSONDict) error {
- err := config.Unmarshal(vmConfig, "desc")
- if err != nil {
- return errors.Wrapf(err, "config.Unmarshal")
- }
- if !vmConfig.IsNeedInjectPasswordByCloudInit {
- if len(vmConfig.UserData) > 0 {
- _, err := cloudinit.ParseUserData(vmConfig.UserData)
- if err != nil {
- return err
- }
- }
- }
- if publicKey, _ := config.GetString("public_key"); len(publicKey) > 0 {
- vmConfig.PublicKey = publicKey
- }
- //目前所写的userData格式仅支持Linux
- if strings.EqualFold(vmConfig.OsType, osprofile.OS_TYPE_LINUX) {
- adminPublicKey, _ := config.GetString("admin_public_key")
- projectPublicKey, _ := config.GetString("project_public_key")
- vmConfig.UserData = generateUserData(adminPublicKey, projectPublicKey, vmConfig.UserData)
- }
- resetPassword := jsonutils.QueryBoolean(config, "reset_password", false)
- vmConfig.Password, _ = config.GetString("password")
- if resetPassword && len(vmConfig.Password) == 0 {
- vmConfig.Password = seclib.RandomPassword2(12)
- }
- if vmConfig.IsNeedInjectPasswordByCloudInit {
- err = vmConfig.InjectPasswordByCloudInit()
- if err != nil {
- return errors.Wrapf(err, "InjectPasswordByCloudInit")
- }
- }
- return nil
- }
- func generateUserData(adminPublicKey, projectPublicKey, oUserData string) string {
- var oCloudConfig *cloudinit.SCloudConfig
- if len(oUserData) > 0 {
- oCloudConfig, _ = cloudinit.ParseUserData(oUserData)
- }
- ansibleUser := cloudinit.NewUser(apis.PUBLIC_CLOUD_ANSIBLE_USER)
- ansibleUser.SshKey(adminPublicKey).SshKey(projectPublicKey).SudoPolicy(cloudinit.USER_SUDO_NOPASSWD)
- cloudConfig := cloudinit.SCloudConfig{
- DisableRoot: 0,
- SshPwauth: cloudinit.SSH_PASSWORD_AUTH_ON,
- Users: []cloudinit.SUser{
- ansibleUser,
- },
- }
- if oCloudConfig != nil {
- cloudConfig.Merge(oCloudConfig)
- }
- return cloudConfig.UserData()
- }
- func (vmConfig *SManagedVMCreateConfig) GetUserData() (string, error) {
- if len(vmConfig.UserData) == 0 {
- return "", nil
- }
- oUserData, err := cloudinit.ParseUserData(vmConfig.UserData)
- if err != nil {
- // 用户输入非标准cloud-init数据
- if !vmConfig.IsNeedInjectPasswordByCloudInit {
- return base64.StdEncoding.EncodeToString([]byte(vmConfig.UserData)), nil
- }
- return "", err
- }
- if strings.EqualFold(vmConfig.OsType, osprofile.OS_TYPE_LINUX) {
- switch vmConfig.UserDataType {
- case CLOUD_SHELL:
- return oUserData.UserDataScriptBase64(), nil
- case CLOUD_SHELL_WITHOUT_ENCRYPT:
- return oUserData.UserDataScript(), nil
- default:
- return oUserData.UserDataBase64(), nil
- }
- } else {
- userData := ""
- switch vmConfig.WindowsUserDataType {
- case CLOUD_EC2:
- userData = oUserData.UserDataEc2()
- default:
- userData = oUserData.UserDataPowerShell()
- }
- if vmConfig.IsWindowsUserDataTypeNeedEncode {
- userData = base64.StdEncoding.EncodeToString([]byte(userData))
- }
- return userData, nil
- }
- }
- func (vmConfig *SManagedVMCreateConfig) InjectPasswordByCloudInit() error {
- loginUser := cloudinit.NewUser(vmConfig.Account)
- loginUser.SudoPolicy(cloudinit.USER_SUDO_NOPASSWD)
- if len(vmConfig.PublicKey) > 0 {
- loginUser.SshKey(vmConfig.PublicKey)
- }
- if len(vmConfig.Password) > 0 {
- loginUser.Password(vmConfig.Password)
- }
- cloudconfig := cloudinit.SCloudConfig{
- DisableRoot: 0,
- SshPwauth: cloudinit.SSH_PASSWORD_AUTH_ON,
- Users: []cloudinit.SUser{
- loginUser,
- },
- }
- if len(vmConfig.UserData) > 0 {
- oCloudConfig, err := cloudinit.ParseUserData(vmConfig.UserData)
- if err != nil {
- return err
- }
- cloudconfig.Merge(oCloudConfig)
- }
- vmConfig.UserData = cloudconfig.UserData()
- return nil
- }
- // +onecloud:model-api-gen
- type ServerVncInput struct {
- // 是否使用原生vnc控制台,此选项仅对openstack有效
- // default: false
- Origin bool `json:"origin"`
- }
- // +onecloud:model-api-gen
- 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"`
- // volcengine
- Region string `json:"region"`
- 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"`
- // sangfor
- Cookie string `json:"cookie"`
- Hypervisor string `json:"hypervisor"`
- }
- type SInstanceUpdateOptions struct {
- NAME string
- HostName string
- Description string
- }
- type SInstanceDeployOptions struct {
- Username string
- Password string
- PublicKey string
- KeypairName string
- DeleteKeypair bool
- UserData string
- }
- type SInstanceModificationType struct {
- InstanceType string
- }
|