内容库模板创建虚拟机
内容库模板创建虚拟机
通过内容库模板创建一台虚拟机,内容通过内容库模板设置。
- template_name: 指定所需使用的内容库模板名称
- cluster_name: 指定虚拟机被部署的集群的集群名称
- vm_name: 虚拟机名称。
返回值为被创建的虚拟机
- Python
- Java
- Go
from cloudtower.api import VmApi, ContentLibraryVmTemplateApi, ClusterApi
from cloudtower.utils import login, wait_tasks
from cloudtower.configuration import Configuration
from cloudtower import ApiClient
import os
configuration = Configuration(host=os.getenv("CLOUDTOWER_ENDPOINT"))
client = ApiClient(configuration)
login(client, os.getenv("CLOUDTOWER_USERNAME"), os.getenv("CLOUDTOWER_PASSWORD"))
def create_vm_from_template(template_name, cluster_name, vm_name):
vm_api = VmApi(client)
cluster_api = ClusterApi(client)
template_api = ContentLibraryVmTemplateApi(client)
cluster = cluster_api.get_clusters({
"where": {
"name": cluster_name
}
})
if len(cluster) == 0:
raise Exception("cluster not found")
template = template_api.get_content_library_vm_templates({
"where": {
"name": template_name
}
})
if len(template) == 0:
raise Exception("template not found")
with_task_vms = vm_api.create_vm_from_content_library_template([
{
"template_id": template[0].id,
"cluster_id": cluster[0].id,
"name": vm_name,
"is_full_copy": False
}
])
tasks = [with_task_vm.task_id for with_task_vm in with_task_vms]
vm_ids = [
with_task_vm.data.id for with_task_vm in with_task_vms]
wait_tasks(tasks, client)
return vm_api.get_vms({
"where": {
"id_in": vm_ids
}
})[0]
package com.smartx.com;
import com.smartx.tower.ApiClient;
import com.smartx.tower.ApiException;
import com.smartx.tower.ClientUtil;
import com.smartx.tower.TaskUtil;
import com.smartx.tower.api.ClusterApi;
import com.smartx.tower.api.ContentLibraryVmTemplateApi;
import com.smartx.tower.api.VmApi;
import com.smartx.tower.model.*;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class App {
public static void main(String[] args) throws ApiException, IOException {
ApiClient client = new ApiClient();
client.setBasePath("http://tower.smartx.com/v2/api");
ClientUtil.login("username", "root", client);
ClusterApi clusterApi = new ClusterApi(client);
ContentLibraryVmTemplateApi contentLibraryVmTemplateApi = new ContentLibraryVmTemplateApi(client);
VmApi vmApi = new VmApi(client);
GetClustersRequestBody getClustersParams = new GetClustersRequestBody()
.where(new ClusterWhereInput()
.name("cluster_name"));
List<Cluster> clusters = clusterApi.getClusters(getClustersParams);
GetContentLibraryVmTemplatesRequestBody getTemplatesParams = new GetContentLibraryVmTemplatesRequestBody()
.where(new ContentLibraryVmTemplateWhereInput()
.name("template_name"));
List<ContentLibraryVmTemplate> templates = contentLibraryVmTemplateApi
.getContentLibraryVmTemplates(getTemplatesParams);
List<VmCreateVmFromContentLibraryTemplateParams> createVmParams = new ArrayList<>();
createVmParams.add(new VmCreateVmFromContentLibraryTemplateParams()
.templateId(templates.get(0).getId())
.clusterId(clusters.get(0).getId())
.name("vm_name")
.isFullCopy(false));
List<WithTaskVm> vms = vmApi.createVmFromContentLibraryTemplate(createVmParams);
List<String> taskIds = vms.stream().map(withTaskObj -> withTaskObj.getTaskId())
.collect(Collectors.toList());
TaskUtil.WaitTasks(taskIds, client);
}
}
package main
import (
"context"
"fmt"
"time"
"github.com/openlyinc/pointy"
apiclient "github.com/smartxworks/cloudtower-go-sdk/v2/client"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/cluster"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/content_library_vm_template"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/vm"
"github.com/smartxworks/cloudtower-go-sdk/v2/models"
"github.com/smartxworks/cloudtower-go-sdk/v2/utils"
"github.com/thoas/go-funk"
)
func main() {
client, err := apiclient.NewWithUserConfig(apiclient.ClientConfig{
Host: "tower.smartx.com",
BasePath: "v2/api",
Schemes: []string{"http"},
}, apiclient.UserConfig{
Name: "Name",
Password: "Password",
Source: models.UserSourceLOCAL,
})
if err != nil {
fmt.Println(err)
return
}
cluster_api := client.Cluster
content_library_vm_template_api := client.ContentLibraryVMTemplate
vm_api := client.VM
get_clusters_params := cluster.NewGetClustersParams()
get_clusters_params.RequestBody = &models.GetClustersRequestBody{
Where: &models.ClusterWhereInput{
Name: pointy.String("cluster_name"),
},
}
rawClusters, err := cluster_api.GetClusters(get_clusters_params)
if err != nil {
fmt.Println(err)
return
}
clusters := rawClusters.Payload
get_templates_params := content_library_vm_template.NewGetContentLibraryVMTemplatesParams()
get_templates_params.RequestBody = &models.GetContentLibraryVMTemplatesRequestBody{
Where: &models.ContentLibraryVMTemplateWhereInput{
Name: pointy.String("template_name"),
},
}
rawTemplates, err := content_library_vm_template_api.GetContentLibraryVMTemplates(get_templates_params)
if err != nil {
fmt.Println(err)
return
}
templates := rawTemplates.Payload
create_vm_params := vm.NewCreateVMFromContentLibraryTemplateParams()
create_vm_params.RequestBody = []*models.VMCreateVMFromContentLibraryTemplateParams{
{
TemplateID: templates[0].ID,
ClusterID: clusters[0].ID,
Name: pointy.String("vm_name"),
IsFullCopy: pointy.Bool(false),
},
}
rawVms, err := vm_api.CreateVMFromContentLibraryTemplate(create_vm_params)
if err != nil {
fmt.Println(err)
return
}
vms := rawVms.Payload
err = utils.WaitTasks(context.Background(), client, funk.Map(vms, func(withTaskObj *models.WithTaskVM) string {
return *withTaskObj.TaskID
}).([]string), 1*time.Second)
if err != nil {
fmt.Println(err)
return
}
}
内容库模板创建虚拟机并编辑虚拟机盘
通过内容库模板创建一台虚拟机,配置虚拟机的磁盘。
- template_name 为模板名称
- cluster_name 为集群名称
- vm_name 为虚拟机名称
- disk_operate 为磁盘操作
使用详见 create_vm_from_template_modify_disk_example 方法。
返回值为被创建的虚拟机
通过内容库模板创建虚拟机时,如果希望对原有的磁盘进行任何修改,可以通过 disk_operate 参数进行配置 disk_operate 参数的类型是 VmDiskOperate,它是一个字典,包含以下字段:
- remove_disks 由于删除指定index的磁盘
- modify_disks 修改现有磁盘的配置,目前仅支持修改总线,如果有其他修改可以通过,删除原有盘
- new_disks 新增磁盘,类型是 VmDiskParams,它是一个字典,包含以下字段:
- mount_cd_roms 挂载 cd-rom
- mount_disks 挂载已有磁盘
- mount_new_create_disks 挂载新磁盘
- Python
- Java
- Go
from cloudtower.api import VmApi, ContentLibraryVmTemplateApi, ClusterApi
from cloudtower.utils import login, wait_tasks
from cloudtower.configuration import Configuration
from cloudtower.models import Bus, VmVolumeElfStoragePolicyType
from cloudtower import ApiClient
import os
configuration = Configuration(host=os.getenv("CLOUDTOWER_ENDPOINT"))
client = ApiClient(configuration)
login(client, os.getenv("CLOUDTOWER_USERNAME"), os.getenv("CLOUDTOWER_PASSWORD"))
def create_vm_from_template_modify_disk(template_name, cluster_name, vm_name, disk_operate):
vm_api = VmApi(client)
cluster_api = ClusterApi(client)
template_api = ContentLibraryVmTemplateApi(client)
cluster = cluster_api.get_clusters({
"where": {
"name": cluster_name
}
})
if len(cluster) == 0:
raise Exception("cluster not found")
template = template_api.get_content_library_vm_templates({
"where": {
"name": template_name
}
})
if len(template) == 0:
raise Exception("template not found")
with_task_vms = vm_api.create_vm_from_content_library_template([
{
"template_id": template[0].id,
"cluster_id": cluster[0].id,
"name": vm_name,
"is_full_copy": False,
"disk_operate": disk_operate
}
])
tasks = [with_task_vm.task_id for with_task_vm in with_task_vms]
vm_ids = [
with_task_vm.data.id for with_task_vm in with_task_vms]
wait_tasks(tasks, client)
return vm_api.get_vms({
"where": {
"id_in": vm_ids
}
})[0]
def create_vm_from_template_modify_disk_example():
disk_operate = {
"remove_disks": {
"disk_index": [0] # 用于删除指定 index 的磁盘,index 从 0 开始计算,这里既是删除第一块磁盘
},
"new_disks": {
"mount_cd_roms": [
{
"boot": 2, # 启动顺序
"content_library_image_id": "" # 指定挂载内容库镜像的 id
}
],
"mount_disks": [
{
"boot": 3, # 启动顺序
"bus": Bus.VIRTIO, # 总线类型
"vm_volume_id": "cljm6x2g1405g0958tp3zkhvh" # 被挂载虚拟卷的 id
}
],
"mount_new_create_disks": [
{
"boot": 4,
"bus": Bus.VIRTIO,
"vm_volume": {
"name": "test", # 新建虚拟卷的名称
"size": 10 * 1024 * 1024 * 1024, # 新建虚拟卷的大小,单位是字节
"elf_storage_policy": VmVolumeElfStoragePolicyType._2_THIN_PROVISION # 存储策略
}
}
]
}
}
create_vm_from_template_modify_disk("template-name", "cluster-name", "vm-name", disk_operate)
package com.smartx.com;
import com.smartx.tower.ApiClient;
import com.smartx.tower.ApiException;
import com.smartx.tower.ClientUtil;
import com.smartx.tower.TaskUtil;
import com.smartx.tower.api.ClusterApi;
import com.smartx.tower.api.ContentLibraryVmTemplateApi;
import com.smartx.tower.api.VmApi;
import com.smartx.tower.model.*;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class App {
public static void main(String[] args) throws ApiException, IOException {
ApiClient client = new ApiClient();
client.setBasePath("http://tower.smartx.com/v2/api");
ClientUtil.login("username", "root", client);
ClusterApi clusterApi = new ClusterApi(client);
ContentLibraryVmTemplateApi contentLibraryVmTemplateApi = new ContentLibraryVmTemplateApi(client);
VmApi vmApi = new VmApi(client);
GetClustersRequestBody getClustersParams = new GetClustersRequestBody()
.where(new ClusterWhereInput()
.name("cluster_name"));
List<Cluster> clusters = clusterApi.getClusters(getClustersParams);
GetContentLibraryVmTemplatesRequestBody getTemplatesParams = new GetContentLibraryVmTemplatesRequestBody()
.where(new ContentLibraryVmTemplateWhereInput()
.name("template_name"));
List<ContentLibraryVmTemplate> templates = contentLibraryVmTemplateApi
.getContentLibraryVmTemplates(getTemplatesParams);
List<VmCreateVmFromContentLibraryTemplateParams> createVmParams = new ArrayList<>();
createVmParams.add(new VmCreateVmFromContentLibraryTemplateParams()
.templateId(templates.get(0).getId())
.clusterId(clusters.get(0).getId())
.name("vm_name")
.isFullCopy(false)
.diskOperate(new VmDiskOperate()
.removeDisks(new VmDiskOperateRemoveDisks()
.addDiskIndexItem(0))
.newDisks(new VmDiskParams()
.addMountCdRomsItem(new VmCdRomParams()
.boot(2)
.contentLibraryImageId(""))
.addMountDisksItem(new MountDisksParams()
.boot(3)
.bus(Bus.fromValue("VIRTIO"))
.vmVolumeId("cljm6x2g1405g0958tp3zkhvh"))
.addMountNewCreateDisksItem(
new MountNewCreateDisksParams()
.boot(4)
.bus(Bus.fromValue(
"VIRTIO"))
.vmVolume(new MountNewCreateDisksParamsVmVolume()
.name("test")
.size(10737418240L)
.elfStoragePolicy(
VmVolumeElfStoragePolicyType
.fromValue("REPLICA_2_THIN_PROVISION")))))));
List<WithTaskVm> vms = vmApi.createVmFromContentLibraryTemplate(createVmParams);
List<String> taskIds = vms.stream().map(withTaskObj -> withTaskObj.getTaskId())
.collect(Collectors.toList());
TaskUtil.WaitTasks(taskIds, client);
}
}
package main
import (
"context"
"fmt"
"time"
"github.com/openlyinc/pointy"
apiclient "github.com/smartxworks/cloudtower-go-sdk/v2/client"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/cluster"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/content_library_vm_template"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/vm"
"github.com/smartxworks/cloudtower-go-sdk/v2/models"
"github.com/smartxworks/cloudtower-go-sdk/v2/utils"
"github.com/thoas/go-funk"
)
func main() {
client, err := apiclient.NewWithUserConfig(apiclient.ClientConfig{
Host: "tower.smartx.com",
BasePath: "v2/api",
Schemes: []string{"http"},
}, apiclient.UserConfig{
Name: "Name",
Password: "Password",
Source: models.UserSourceLOCAL,
})
if err != nil {
fmt.Println(err)
return
}
cluster_api := client.Cluster
content_library_vm_template_api := client.ContentLibraryVMTemplate
vm_api := client.VM
get_clusters_params := cluster.NewGetClustersParams()
get_clusters_params.RequestBody = &models.GetClustersRequestBody{
Where: &models.ClusterWhereInput{
Name: pointy.String("cluster_name"),
},
}
rawClusters, err := cluster_api.GetClusters(get_clusters_params)
if err != nil {
fmt.Println(err)
return
}
clusters := rawClusters.Payload
get_templates_params := content_library_vm_template.NewGetContentLibraryVMTemplatesParams()
get_templates_params.RequestBody = &models.GetContentLibraryVMTemplatesRequestBody{
Where: &models.ContentLibraryVMTemplateWhereInput{
Name: pointy.String("template_name"),
},
}
rawTemplates, err := content_library_vm_template_api.GetContentLibraryVMTemplates(get_templates_params)
if err != nil {
fmt.Println(err)
return
}
templates := rawTemplates.Payload
create_vm_params := vm.NewCreateVMFromContentLibraryTemplateParams()
create_vm_params.RequestBody = []*models.VMCreateVMFromContentLibraryTemplateParams{
{
TemplateID: templates[0].ID,
ClusterID: clusters[0].ID,
Name: pointy.String("vm_name"),
IsFullCopy: pointy.Bool(false),
DiskOperate: &models.VMDiskOperate{
RemoveDisks: &models.VMDiskOperateRemoveDisks{
DiskIndex: []int32{0},
},
NewDisks: &models.VMDiskParams{
MountCdRoms: []*models.VMCdRomParams{
{
Boot: pointy.Int32(2),
ContentLibraryImageID: pointy.String(""),
},
},
MountDisks: []*models.MountDisksParams{
{
Boot: pointy.Int32(3),
Bus: models.BusVIRTIO.Pointer(),
VMVolumeID: pointy.String("cljm6x2g1405g0958tp3zkhvh"),
},
},
MountNewCreateDisks: []*models.MountNewCreateDisksParams{
{
Boot: pointy.Int32(4),
Bus: models.BusVIRTIO.Pointer(),
VMVolume: &models.MountNewCreateDisksParamsVMVolume{
Name: pointy.String("test"),
Size: pointy.Int64(10737418240),
ElfStoragePolicy: models.VMVolumeElfStoragePolicyTypeREPLICA2THINPROVISION.Pointer(),
},
},
},
},
},
},
}
rawVms, err := vm_api.CreateVMFromContentLibraryTemplate(create_vm_params)
if err != nil {
fmt.Println(err)
return
}
vms := rawVms.Payload
err = utils.WaitTasks(context.Background(), client, funk.Map(vms, func(withTaskObj *models.WithTaskVM) string {
return *withTaskObj.TaskID
}).([]string), 1*time.Second)
if err != nil {
fmt.Println(err)
return
}
}
通过内容库模板创建并编辑虚拟网卡
通过内容库模板创建一台虚拟机,配置虚拟机的网卡
- template_name 为模板名称
- cluster_name 为集群名称
- vm_name 为虚拟机名称
- nic_params 为磁盘操作
使用详见 create_vm_from_template_modified_nic_example 方法。
返回值为被创建的虚拟机。
通过内容库模板创建虚拟机时,如果不传递 vm_nics 参数,会默认使用模板的网卡配置,如果需要修改网卡配置,可以传递 vm_nics 参数, vm_nics 参数是一个列表,列表中的每个元素都是一个字典:
- connect_vlan_id 网卡对应虚拟机网络的 id,并非虚拟机网络的 vlan_id
- enabled 是否启用网卡
- model 网卡类型,可以使用 VmNicModel 类的属性,如 VmNicModel.VIRTIO 创建虚拟机时并不支持修改网卡的 ip,mac,gateway,subnet mask,如果需要配置ip,子网,网关,可以通过 cloudinit 来实现,需要模板支持 cloudinit
- Python
- Java
- Go
from cloudtower.api import VmApi, ContentLibraryVmTemplateApi, ClusterApi
from cloudtower.utils import login, wait_tasks
from cloudtower.configuration import Configuration
from cloudtower.models import Bus, VmNicModel
from cloudtower import ApiClient
import os
configuration = Configuration(host=os.getenv("CLOUDTOWER_ENDPOINT"))
client = ApiClient(configuration)
login(client, os.getenv("CLOUDTOWER_USERNAME"), os.getenv("CLOUDTOWER_PASSWORD"))
def create_vm_from_template_modified_nic(template_name, cluster_name, vm_name, nic_params):
vm_api = VmApi(client)
cluster_api = ClusterApi(client)
template_api = ContentLibraryVmTemplateApi(client)
cluster = cluster_api.get_clusters({
"where": {
"name": cluster_name
}
})
if len(cluster) == 0:
raise Exception("cluster not found")
template = template_api.get_content_library_vm_templates({
"where": {
"name": template_name
}
})
if len(template) == 0:
raise Exception("template not found")
with_task_vms = vm_api.create_vm_from_content_library_template([
{
"template_id": template[0].id,
"cluster_id": cluster[0].id,
"name": vm_name,
"is_full_copy": False,
"vm_nics": nic_params
}
])
tasks = [with_task_vm.task_id for with_task_vm in with_task_vms]
vm_ids = [
with_task_vm.data.id for with_task_vm in with_task_vms]
wait_tasks(tasks, client)
return vm_api.get_vms({
"where": {
"id_in": vm_ids
}
})[0]
def create_vm_from_template_modified_nic_example():
nic_params = [
{
"connect_vlan_id": "vlan_id",
"enabled": True,
"model": VmNicModel.VIRTIO
}
]
create_vm_from_template_modified_nic("template_name", "cluster_name", "vm_name", nic_params)
package com.smartx.com;
import com.smartx.tower.ApiClient;
import com.smartx.tower.ApiException;
import com.smartx.tower.ClientUtil;
import com.smartx.tower.TaskUtil;
import com.smartx.tower.api.ClusterApi;
import com.smartx.tower.api.ContentLibraryVmTemplateApi;
import com.smartx.tower.api.VmApi;
import com.smartx.tower.model.*;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class App {
public static void main(String[] args) throws ApiException, IOException {
ApiClient client = new ApiClient();
client.setBasePath("http://tower.smartx.com/v2/api");
ClientUtil.login("username", "root", client);
ClusterApi clusterApi = new ClusterApi(client);
ContentLibraryVmTemplateApi contentLibraryVmTemplateApi = new ContentLibraryVmTemplateApi(client);
VmApi vmApi = new VmApi(client);
GetClustersRequestBody getClustersParams = new GetClustersRequestBody()
.where(new ClusterWhereInput()
.name("cluster_name"));
List<Cluster> clusters = clusterApi.getClusters(getClustersParams);
GetContentLibraryVmTemplatesRequestBody getTemplatesParams = new GetContentLibraryVmTemplatesRequestBody()
.where(new ContentLibraryVmTemplateWhereInput()
.name("template_name"));
List<ContentLibraryVmTemplate> templates = contentLibraryVmTemplateApi
.getContentLibraryVmTemplates(getTemplatesParams);
List<VmCreateVmFromContentLibraryTemplateParams> createVmParams = new ArrayList<>();
createVmParams.add(new VmCreateVmFromContentLibraryTemplateParams()
.templateId(templates.get(0).getId())
.clusterId(clusters.get(0).getId())
.name("vm_name")
.isFullCopy(false)
.addVmNicsItem(new VmNicParams()
.connectVlanId("vlan_id")
.enabled(true)
.model(VmNicModel.fromValue("VIRTIO"))));
List<WithTaskVm> vms = vmApi.createVmFromContentLibraryTemplate(createVmParams);
List<String> taskIds = vms.stream().map(withTaskObj -> withTaskObj.getTaskId()).collect(Collectors.toList());
TaskUtil.WaitTasks(taskIds, client);
}
}
package main
import (
"context"
"fmt"
"time"
"github.com/openlyinc/pointy"
apiclient "github.com/smartxworks/cloudtower-go-sdk/v2/client"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/cluster"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/content_library_vm_template"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/vm"
"github.com/smartxworks/cloudtower-go-sdk/v2/models"
"github.com/smartxworks/cloudtower-go-sdk/v2/utils"
"github.com/thoas/go-funk"
)
func main() {
client, err := apiclient.NewWithUserConfig(apiclient.ClientConfig{
Host: "tower.smartx.com",
BasePath: "v2/api",
Schemes: []string{"http"},
}, apiclient.UserConfig{
Name: "Name",
Password: "Password",
Source: models.UserSourceLOCAL,
})
if err != nil {
fmt.Println(err)
return
}
cluster_api := client.Cluster
content_library_vm_template_api := client.ContentLibraryVMTemplate
vm_api := client.VM
get_clusters_params := cluster.NewGetClustersParams()
get_clusters_params.RequestBody = &models.GetClustersRequestBody{
Where: &models.ClusterWhereInput{
Name: pointy.String("cluster_name"),
},
}
rawClusters, err := cluster_api.GetClusters(get_clusters_params)
if err != nil {
fmt.Println(err)
return
}
clusters := rawClusters.Payload
get_templates_params := content_library_vm_template.NewGetContentLibraryVMTemplatesParams()
get_templates_params.RequestBody = &models.GetContentLibraryVMTemplatesRequestBody{
Where: &models.ContentLibraryVMTemplateWhereInput{
Name: pointy.String("template_name"),
},
}
rawTemplates, err := content_library_vm_template_api.GetContentLibraryVMTemplates(get_templates_params)
if err != nil {
fmt.Println(err)
return
}
templates := rawTemplates.Payload
create_vm_params := vm.NewCreateVMFromContentLibraryTemplateParams()
create_vm_params.RequestBody = []*models.VMCreateVMFromContentLibraryTemplateParams{
{
TemplateID: templates[0].ID,
ClusterID: clusters[0].ID,
Name: pointy.String("vm_name"),
IsFullCopy: pointy.Bool(false),
VMNics: []*models.VMNicParams{
{
ConnectVlanID: pointy.String("vlan_id"),
Enabled: pointy.Bool(true),
Model: models.VMNicModelVIRTIO.Pointer(),
},
},
},
}
rawVms, err := vm_api.CreateVMFromContentLibraryTemplate(create_vm_params)
if err != nil {
fmt.Println(err)
return
}
vms := rawVms.Payload
err = utils.WaitTasks(context.Background(), client, funk.Map(vms, func(withTaskObj *models.WithTaskVM) string {
return *withTaskObj.TaskID
}).([]string), 1*time.Second)
if err != nil {
fmt.Println(err)
return
}
}
通过内容库模板创建并编辑 cloud-init
通过内容库模板创建一台虚拟机,配置虚拟机的 cloud-init,需要模板启用
- template_name: 模板名称
- cluster_name: 集群名称
- vm_name: 虚拟机名称
- cloud_init: cloud-init 配置,使用详见 create_vm_from_template_with_cloudinit_example 方法
返回值为被创建的虚拟机。
cloudinit 可以用于配置虚拟机的初始化,例如配置网络、配置默认账户密码等,需要模板创建时已经安装 cloud-init 或者 cloudbase-init 服务才能正常工作
cloud_init 配置项是 TemplateCloudInit 类型,是一个字典,包含以下字段
- default_user_password: 配置默认用户密码
- nameservers: dns 服务地址,是一个字符串列表,最多支持配置3个
- networks: 网络配置,一个字典列表
- ip_address: ip 地址,配置静态地址后必填
- netmask: 子网,配置静态地址后必填
- nic_index: 配置网卡的顺序,以 0 为起始
- routes: 静态路由配置,一个字典列表
- gateway: 网关地址
- network: 目标网络
- netmask: 目标子网
- hostname: 主机名
- public_keys: 登陆用的公钥
- user_data: 用户数据配置
- Python
- Java
- Go
from cloudtower.api import VmApi, ContentLibraryVmTemplateApi, ClusterApi
from cloudtower.utils import login, wait_tasks
from cloudtower.configuration import Configuration
from cloudtower import ApiClient
import os
configuration = Configuration(host=os.getenv("CLOUDTOWER_ENDPOINT"))
client = ApiClient(configuration)
login(client, os.getenv("CLOUDTOWER_USERNAME"), os.getenv("CLOUDTOWER_PASSWORD"))
def create_vm_from_template_with_cloudinit(template_name, cluster_name, vm_name, cloud_init):
vm_api = VmApi(client)
cluster_api = ClusterApi(client)
template_api = ContentLibraryVmTemplateApi(client)
cluster = cluster_api.get_clusters({
"where": {
"name": cluster_name
}
})
if len(cluster) == 0:
raise Exception("cluster not found")
template = template_api.get_content_library_vm_templates({
"where": {
"name": template_name
}
})
if len(template) == 0:
raise Exception("template not found")
with_task_vms = vm_api.create_vm_from_content_library_template([
{
"template_id": template[0].id,
"cluster_id": cluster[0].id,
"name": vm_name,
"is_full_copy": False,
"cloud_init": cloud_init
}
])
tasks = [with_task_vm.task_id for with_task_vm in with_task_vms]
vm_ids = [
with_task_vm.data.id for with_task_vm in with_task_vms]
wait_tasks(tasks, client)
return vm_api.get_vms({
"where": {
"id_in": vm_ids
}
})[0]
def create_vm_from_template_with_cloudinit_example():
cloud_init = {
"default_user_password": "password",
"nameservers": [
"114.114.114.114"
],
"networks": [
{
"ip_address": "192.168.20.1",
"netmask": "255.255.240.0",
"nic_index": 0,
"routes": [
{
"gateway": "192.168.16.1", # 默认网关配置
"network": "0.0.0.0",
"netmask": "0.0.0.0",
},
]
}
],
"hostname": "test",
"public_keys": [
"key_content"
],
"user_data": "user_data"
}
create_vm_from_template_with_cloudinit("template_name", "cluster_name", "vm_name", cloud_init)
package com.smartx.com;
import com.smartx.tower.ApiClient;
import com.smartx.tower.ApiException;
import com.smartx.tower.ClientUtil;
import com.smartx.tower.TaskUtil;
import com.smartx.tower.api.ClusterApi;
import com.smartx.tower.api.ContentLibraryVmTemplateApi;
import com.smartx.tower.api.VmApi;
import com.smartx.tower.model.*;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class App {
public static void main(String[] args) throws ApiException, IOException {
ApiClient client = new ApiClient();
client.setBasePath("http://tower.smartx.com/v2/api");
ClientUtil.login("username", "root", client);
ClusterApi clusterApi = new ClusterApi(client);
ContentLibraryVmTemplateApi contentLibraryVmTemplateApi = new ContentLibraryVmTemplateApi(client);
VmApi vmApi = new VmApi(client);
GetClustersRequestBody getClustersParams = new GetClustersRequestBody()
.where(new ClusterWhereInput()
.name("cluster_name"));
List<Cluster> clusters = clusterApi.getClusters(getClustersParams);
GetContentLibraryVmTemplatesRequestBody getTemplatesParams = new GetContentLibraryVmTemplatesRequestBody()
.where(new ContentLibraryVmTemplateWhereInput()
.name("template_name"));
List<ContentLibraryVmTemplate> templates = contentLibraryVmTemplateApi
.getContentLibraryVmTemplates(getTemplatesParams);
List<VmCreateVmFromContentLibraryTemplateParams> createVmParams = new ArrayList<>();
createVmParams.add(new VmCreateVmFromContentLibraryTemplateParams()
.templateId(templates.get(0).getId())
.clusterId(clusters.get(0).getId())
.name("vm_name")
.isFullCopy(false)
.cloudInit(new TemplateCloudInit()
.defaultUserPassword("password")
.addNameserversItem("114.114.114.114")
.addNetworksItem(new CloudInitNetWork()
.ipAddress("192.168.20.1")
.netmask("255.255.240.0")
.nicIndex(0)
.addRoutesItem(new CloudInitNetWorkRoute()
.gateway("192.168.16.1")
.network("0.0.0.0")
.netmask("0.0.0.0")))
.hostname("test")
.addPublicKeysItem("key_content")
.userData("user_data")));
List<WithTaskVm> vms = vmApi.createVmFromContentLibraryTemplate(createVmParams);
List<String> taskIds = vms.stream().map(withTaskObj -> withTaskObj.getTaskId()).collect(Collectors.toList());
TaskUtil.WaitTasks(taskIds, client);
}
}
package main
import (
"context"
"fmt"
"time"
"github.com/openlyinc/pointy"
apiclient "github.com/smartxworks/cloudtower-go-sdk/v2/client"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/cluster"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/content_library_vm_template"
"github.com/smartxworks/cloudtower-go-sdk/v2/client/vm"
"github.com/smartxworks/cloudtower-go-sdk/v2/models"
"github.com/smartxworks/cloudtower-go-sdk/v2/utils"
"github.com/thoas/go-funk"
)
func main() {
client, err := apiclient.NewWithUserConfig(apiclient.ClientConfig{
Host: "tower.smartx.com",
BasePath: "v2/api",
Schemes: []string{"http"},
}, apiclient.UserConfig{
Name: "Name",
Password: "Password",
Source: models.UserSourceLOCAL,
})
if err != nil {
fmt.Println(err)
return
}
cluster_api := client.Cluster
content_library_vm_template_api := client.ContentLibraryVMTemplate
vm_api := client.VM
get_clusters_params := cluster.NewGetClustersParams()
get_clusters_params.RequestBody = &models.GetClustersRequestBody{
Where: &models.ClusterWhereInput{
Name: pointy.String("cluster_name"),
},
}
rawClusters, err := cluster_api.GetClusters(get_clusters_params)
if err != nil {
fmt.Println(err)
return
}
clusters := rawClusters.Payload
get_templates_params := content_library_vm_template.NewGetContentLibraryVMTemplatesParams()
get_templates_params.RequestBody = &models.GetContentLibraryVMTemplatesRequestBody{
Where: &models.ContentLibraryVMTemplateWhereInput{
Name: pointy.String("template_name"),
},
}
rawTemplates, err := content_library_vm_template_api.GetContentLibraryVMTemplates(get_templates_params)
if err != nil {
fmt.Println(err)
return
}
templates := rawTemplates.Payload
create_vm_params := vm.NewCreateVMFromContentLibraryTemplateParams()
create_vm_params.RequestBody = []*models.VMCreateVMFromContentLibraryTemplateParams{
{
TemplateID: templates[0].ID,
ClusterID: clusters[0].ID,
Name: pointy.String("vm_name"),
IsFullCopy: pointy.Bool(false),
CloudInit: &models.TemplateCloudInit{
DefaultUserPassword: pointy.String("password"),
Nameservers: []string{"114.114.114.114"},
Networks: []*models.CloudInitNetWork{
{
IPAddress: pointy.String("192.168.20.1"),
Netmask: pointy.String("255.255.240.0"),
NicIndex: pointy.Int32(0),
Routes: []*models.CloudInitNetWorkRoute{
{
Gateway: pointy.String("192.168.16.1"),
Network: pointy.String("0.0.0.0"),
Netmask: pointy.String("0.0.0.0"),
},
},
},
},
Hostname: pointy.String("test"),
PublicKeys: []string{"key_content"},
UserData: pointy.String("user_data"),
},
},
}
rawVms, err := vm_api.CreateVMFromContentLibraryTemplate(create_vm_params)
if err != nil {
fmt.Println(err)
return
}
vms := rawVms.Payload
err = utils.WaitTasks(context.Background(), client, funk.Map(vms, func(withTaskObj *models.WithTaskVM) string {
return *withTaskObj.TaskID
}).([]string), 1*time.Second)
if err != nil {
fmt.Println(err)
return
}
}