in pkg/cloud/instance.go [126:188]
func (c *client) GetOrCreateVMInstance(
csMachine *infrav1.CloudStackMachine,
machine *capiv1.Machine,
csCluster *infrav1.CloudStackCluster,
userData string) error {
// Check if VM instance already exists.
if err := c.ResolveVMInstanceDetails(csMachine); err == nil ||
!strings.Contains(strings.ToLower(err.Error()), "no match") {
return err
}
offeringID, err := c.ResolveServiceOffering(csMachine)
if err != nil {
return err
}
templateID, err := c.ResolveTemplate(csCluster, csMachine)
if err != nil {
return err
}
// Create VM instance.
p := c.cs.VirtualMachine.NewDeployVirtualMachineParams(offeringID, templateID, csCluster.Status.ZoneID)
p.SetNetworkids([]string{csCluster.Status.NetworkID})
setIfNotEmpty(csMachine.Name, p.SetName)
setIfNotEmpty(csMachine.Name, p.SetDisplayname)
setIfNotEmpty(csMachine.Spec.SSHKey, p.SetKeypair)
if compressedAndEncodedUserData, err := CompressAndEncodeString(userData); err != nil {
return err
} else {
setIfNotEmpty(compressedAndEncodedUserData, p.SetUserdata)
}
if len(csMachine.Spec.AffinityGroupIds) > 0 {
p.SetAffinitygroupids(csMachine.Spec.AffinityGroupIds)
}
setIfNotEmpty(csCluster.Spec.Account, p.SetAccount)
setIfNotEmpty(csCluster.Status.DomainID, p.SetDomainid)
// If this VM instance is a control plane, consider setting it's IP.
_, isControlPlanceMachine := machine.ObjectMeta.Labels["cluster.x-k8s.io/control-plane"]
if isControlPlanceMachine && csCluster.Status.NetworkType == NetworkTypeShared {
// If the specified control plane endpoint is an IP address, specify the IP address of this VM instance.
if net.ParseIP(csCluster.Spec.ControlPlaneEndpoint.Host) != nil {
p.SetIpaddress(csCluster.Spec.ControlPlaneEndpoint.Host)
}
}
if csMachine.Spec.Details != nil {
p.SetDetails(csMachine.Spec.Details)
}
deployVMResp, err := c.cs.VirtualMachine.DeployVirtualMachine(p)
if err != nil {
return err
}
csMachine.Spec.InstanceID = pointer.StringPtr(deployVMResp.Id)
// Resolve uses a VM metrics request response to fill cloudstack machine status.
// The deployment response is insufficient.
return c.ResolveVMInstanceDetails(csMachine)
}