driver fix; start/stop compute
This commit is contained in:
@@ -27,6 +27,7 @@ package decort
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
// "net/url"
|
// "net/url"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -36,20 +37,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Parse list of all disks from API compute/get into a list of "extra disks" attached to this compute
|
// Parse list of all disks from API compute/get into a list of "extra disks" attached to this compute
|
||||||
// Extra disks are all compute disks but a boot disk.
|
// Extra disks are all compute disks but a boot disk.
|
||||||
func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
||||||
// this return value will be used to d.Set("extra_disks",) item of dataSourceCompute schema,
|
// this return value will be used to d.Set("extra_disks",) item of dataSourceCompute schema,
|
||||||
// which is a simple list of integer disk IDs excluding boot disk ID
|
// which is a simple list of integer disk IDs excluding boot disk ID
|
||||||
length := len(disks)
|
length := len(disks)
|
||||||
log.Debugf("parseComputeDisksToExtraDisks: called for %d disks", length)
|
log.Debugf("parseComputeDisksToExtraDisks: called for %d disks", length)
|
||||||
|
|
||||||
if length == 0 || ( length == 1 && disks[0].Type == "B" ) {
|
if length == 0 || (length == 1 && disks[0].Type == "B") {
|
||||||
// the disk list is empty (which is kind of strange - diskless compute?), or
|
// the disk list is empty (which is kind of strange - diskless compute?), or
|
||||||
// there is only one disk in the list and it is a boot disk;
|
// there is only one disk in the list and it is a boot disk;
|
||||||
// as we skip boot disks, the result will be of 0 length anyway
|
// as we skip boot disks, the result will be of 0 length anyway
|
||||||
return make([]interface{}, 0)
|
return make([]interface{}, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make([]interface{}, length-1)
|
result := make([]interface{}, length-1)
|
||||||
idx := 0
|
idx := 0
|
||||||
for _, value := range disks {
|
for _, value := range disks {
|
||||||
@@ -62,7 +63,7 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
|||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: this is a legacy function, which is not used as of rc-1.10
|
// NOTE: this is a legacy function, which is not used as of rc-1.10
|
||||||
@@ -70,18 +71,18 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
|||||||
func parseComputeDisks(disks []DiskRecord) []interface{} {
|
func parseComputeDisks(disks []DiskRecord) []interface{} {
|
||||||
// Return value was designed to d.Set("disks",) item of dataSourceCompute schema
|
// Return value was designed to d.Set("disks",) item of dataSourceCompute schema
|
||||||
// However, this item was excluded from the schema as it is not directly
|
// However, this item was excluded from the schema as it is not directly
|
||||||
// managed through Terraform
|
// managed through Terraform
|
||||||
length := len(disks)
|
length := len(disks)
|
||||||
log.Debugf("parseComputeDisks: called for %d disks", length)
|
log.Debugf("parseComputeDisks: called for %d disks", length)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if length == 1 && disks[0].Type == "B" {
|
if length == 1 && disks[0].Type == "B" {
|
||||||
// there is only one disk in the list and it is a boot disk
|
// there is only one disk in the list and it is a boot disk
|
||||||
// as we skip boot disks, the result will be of 0 lenght
|
// as we skip boot disks, the result will be of 0 lenght
|
||||||
length = 0
|
length = 0
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
result := []interface{}{}
|
result := []interface{}{}
|
||||||
|
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
@@ -90,10 +91,10 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
|
|||||||
|
|
||||||
for _, value := range disks {
|
for _, value := range disks {
|
||||||
/*
|
/*
|
||||||
if value.Type == "B" {
|
if value.Type == "B" {
|
||||||
// skip boot disk when parsing the list of disks
|
// skip boot disk when parsing the list of disks
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
elem := make(map[string]interface{})
|
elem := make(map[string]interface{})
|
||||||
// keys in this map should correspond to the Schema definition
|
// keys in this map should correspond to the Schema definition
|
||||||
@@ -112,11 +113,11 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
|
|||||||
// elem["status"] = value.Status
|
// elem["status"] = value.Status
|
||||||
// elem["tech_status"] = value.TechStatus
|
// elem["tech_status"] = value.TechStatus
|
||||||
elem["compute_id"] = value.ComputeID
|
elem["compute_id"] = value.ComputeID
|
||||||
|
|
||||||
result = append(result, elem)
|
result = append(result, elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseBootDiskSize(disks []DiskRecord) int {
|
func parseBootDiskSize(disks []DiskRecord) int {
|
||||||
@@ -131,7 +132,7 @@ func parseBootDiskSize(disks []DiskRecord) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseBootDiskId(disks []DiskRecord) uint {
|
func parseBootDiskId(disks []DiskRecord) uint {
|
||||||
@@ -146,10 +147,10 @@ func parseBootDiskId(disks []DiskRecord) uint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the list of interfaces from compute/get response into a list of networks
|
// Parse the list of interfaces from compute/get response into a list of networks
|
||||||
// attached to this compute
|
// attached to this compute
|
||||||
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
||||||
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
||||||
@@ -172,8 +173,9 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
|||||||
result = append(result, elem)
|
result = append(result, elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]interface{} {
|
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]interface{} {
|
||||||
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
||||||
@@ -196,16 +198,15 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]int
|
|||||||
result[i] = elem
|
result[i] = elem
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// NOTE: this function is retained for historical purposes and actually not used as of rc-1.10
|
// NOTE: this function is retained for historical purposes and actually not used as of rc-1.10
|
||||||
func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
|
func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
|
||||||
// return value was designed to d.Set("interfaces",) item of dataSourceCompute schema
|
// return value was designed to d.Set("interfaces",) item of dataSourceCompute schema
|
||||||
// However, this item was excluded from the schema as it is not directly
|
// However, this item was excluded from the schema as it is not directly
|
||||||
// managed through Terraform
|
// managed through Terraform
|
||||||
length := len(ifaces)
|
length := len(ifaces)
|
||||||
log.Debugf("parseComputeInterfaces: called for %d ifaces", length)
|
log.Debugf("parseComputeInterfaces: called for %d ifaces", length)
|
||||||
|
|
||||||
@@ -237,7 +238,7 @@ func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
|
|||||||
result[i] = elem
|
result[i] = elem
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||||
@@ -274,6 +275,12 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
|||||||
// d.Set("status", model.Status)
|
// d.Set("status", model.Status)
|
||||||
// d.Set("tech_status", model.TechStatus)
|
// d.Set("tech_status", model.TechStatus)
|
||||||
|
|
||||||
|
if model.TechStatus == "STARTED" {
|
||||||
|
d.Set("started", true)
|
||||||
|
} else {
|
||||||
|
d.Set("started", false)
|
||||||
|
}
|
||||||
|
|
||||||
if len(model.Disks) > 0 {
|
if len(model.Disks) > 0 {
|
||||||
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(model.Disks))
|
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(model.Disks))
|
||||||
if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil {
|
if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil {
|
||||||
@@ -403,24 +410,24 @@ func dataSourceCompute() *schema.Resource {
|
|||||||
},
|
},
|
||||||
|
|
||||||
"extra_disks": {
|
"extra_disks": {
|
||||||
Type: schema.TypeSet,
|
Type: schema.TypeSet,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
MaxItems: MaxExtraDisksPerCompute,
|
MaxItems: MaxExtraDisksPerCompute,
|
||||||
Elem: &schema.Schema {
|
Elem: &schema.Schema{
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
},
|
},
|
||||||
Description: "IDs of the extra disk(s) attached to this compute.",
|
Description: "IDs of the extra disk(s) attached to this compute.",
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
"disks": {
|
"disks": {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
||||||
|
},
|
||||||
|
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
||||||
},
|
},
|
||||||
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
|
||||||
},
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"network": {
|
"network": {
|
||||||
@@ -434,14 +441,14 @@ func dataSourceCompute() *schema.Resource {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
"interfaces": {
|
"interfaces": {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: interfaceSubresourceSchemaMake(),
|
Schema: interfaceSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Specification for the virtual NICs configured on this compute instance.",
|
||||||
},
|
},
|
||||||
Description: "Specification for the virtual NICs configured on this compute instance.",
|
|
||||||
},
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"os_users": {
|
"os_users": {
|
||||||
@@ -465,24 +472,31 @@ func dataSourceCompute() *schema.Resource {
|
|||||||
Description: "Placeholder for cloud_init parameters.",
|
Description: "Placeholder for cloud_init parameters.",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"started": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Description: "Is compute started.",
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
"status": {
|
"status": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "Current model status of this compute instance.",
|
Description: "Current model status of this compute instance.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"tech_status": {
|
"tech_status": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "Current technical status of this compute instance.",
|
Description: "Current technical status of this compute instance.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"internal_ip": {
|
"internal_ip": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "Internal IP address of this Compute.",
|
Description: "Internal IP address of this Compute.",
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,12 +105,12 @@ type ResgroupUpdateParam struct {
|
|||||||
// structures related to /cloudapi/rg/get API call
|
// structures related to /cloudapi/rg/get API call
|
||||||
//
|
//
|
||||||
type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get
|
type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get
|
||||||
Cpu int `json:"CU_C"` // CPU count in pcs
|
Cpu int `json:"CU_C"` // CPU count in pcs
|
||||||
Ram float64 `json:"CU_M"` // RAM volume in MB, it is STILL reported as FLOAT
|
Ram float64 `json:"CU_M"` // RAM volume in MB, it is STILL reported as FLOAT
|
||||||
Disk int `json:"CU_D"` // Disk capacity in GB
|
Disk int `json:"CU_D"` // Disk capacity in GB
|
||||||
ExtIPs int `json:"CU_I"` // Ext IPs count
|
ExtIPs int `json:"CU_I"` // Ext IPs count
|
||||||
ExtTraffic int `json:"CU_NP"` // Ext network traffic
|
ExtTraffic int `json:"CU_NP"` // Ext network traffic
|
||||||
GpuUnits int `json:"gpu_units"` // GPU count
|
GpuUnits int `json:"gpu_units"` // GPU count
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResourceRecord struct { // this is how actual usage is reported by /api/.../rg/get
|
type ResourceRecord struct { // this is how actual usage is reported by /api/.../rg/get
|
||||||
@@ -130,27 +130,27 @@ type UsageRecord struct {
|
|||||||
const ResgroupGetAPI = "/restmachine/cloudapi/rg/get"
|
const ResgroupGetAPI = "/restmachine/cloudapi/rg/get"
|
||||||
|
|
||||||
type ResgroupGetResp struct {
|
type ResgroupGetResp struct {
|
||||||
ACLs []UserAclRecord `json:"ACLs"`
|
ACLs []UserAclRecord `json:"ACLs"`
|
||||||
Usage UsageRecord `json:"Resources"`
|
Usage UsageRecord `json:"Resources"`
|
||||||
AccountID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
AccountName string `json:"accountName"`
|
AccountName string `json:"accountName"`
|
||||||
GridID int `json:"gid"`
|
GridID int `json:"gid"`
|
||||||
CreatedBy string `json:"createdBy"`
|
CreatedBy string `json:"createdBy"`
|
||||||
CreatedTime uint64 `json:"createdTime"`
|
CreatedTime uint64 `json:"createdTime"`
|
||||||
DefaultNetID int `json:"def_net_id"`
|
DefaultNetID int `json:"def_net_id"`
|
||||||
DefaultNetType string `json:"def_net_type"`
|
DefaultNetType string `json:"def_net_type"`
|
||||||
DeletedBy string `json:"deletedBy"`
|
DeletedBy string `json:"deletedBy"`
|
||||||
DeletedTime uint64 `json:"deletedTime"`
|
DeletedTime uint64 `json:"deletedTime"`
|
||||||
Desc string `json:"desc"`
|
Desc string `json:"desc"`
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
LockStatus string `json:"lockStatus"`
|
LockStatus string `json:"lockStatus"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Quota QuotaRecord `json:"resourceLimits"`
|
Quota QuotaRecord `json:"resourceLimits"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
UpdatedBy string `json:"updatedBy"`
|
UpdatedBy string `json:"updatedBy"`
|
||||||
UpdatedTime uint64 `json:"updatedTime"`
|
UpdatedTime uint64 `json:"updatedTime"`
|
||||||
Vins []int `json:"vins"`
|
Vins []int `json:"vins"`
|
||||||
Computes []int `json:"vms"`
|
Computes []int `json:"vms"`
|
||||||
|
|
||||||
Ignored map[string]interface{} `json:"-"`
|
Ignored map[string]interface{} `json:"-"`
|
||||||
}
|
}
|
||||||
@@ -187,22 +187,23 @@ const KvmX86CreateAPI = "/restmachine/cloudapi/kvmx86/create"
|
|||||||
const KvmPPCCreateAPI = "/restmachine/cloudapi/kvmppc/create"
|
const KvmPPCCreateAPI = "/restmachine/cloudapi/kvmppc/create"
|
||||||
|
|
||||||
type KvmVmCreateParam struct { // this is unified structure for both x86 and PPC based KVM VMs creation
|
type KvmVmCreateParam struct { // this is unified structure for both x86 and PPC based KVM VMs creation
|
||||||
RgID uint `json:"rgId"`
|
RgID uint `json:"rgId"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Cpu int `json:"cpu"`
|
Cpu int `json:"cpu"`
|
||||||
Ram int `json:"ram"`
|
Ram int `json:"ram"`
|
||||||
ImageID int `json:"imageId"`
|
ImageID int `json:"imageId"`
|
||||||
BootDisk int `json:"bootDisk"`
|
BootDisk int `json:"bootDisk"`
|
||||||
NetType string `json:"netType"`
|
NetType string `json:"netType"`
|
||||||
NetId int `json:"netId"`
|
NetId int `json:"netId"`
|
||||||
IPAddr string `json:"ipAddr"`
|
IPAddr string `json:"ipAddr"`
|
||||||
UserData string `json:"userdata"`
|
UserData string `json:"userdata"`
|
||||||
Desc string `json:"desc"`
|
Desc string `json:"desc"`
|
||||||
Start bool `json:"start"`
|
Start bool `json:"start"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// structures related to cloudapi/compute/start API
|
// structures related to cloudapi/compute/start API
|
||||||
const ComputeStartAPI = "/restmachine/cloudapi/compute/start"
|
const ComputeStartAPI = "/restmachine/cloudapi/compute/start"
|
||||||
|
const ComputeStopAPI = "/restmachine/cloudapi/compute/stop"
|
||||||
|
|
||||||
// structures related to cloudapi/compute/delete API
|
// structures related to cloudapi/compute/delete API
|
||||||
const ComputeDeleteAPI = "/restmachine/cloudapi/compute/delete"
|
const ComputeDeleteAPI = "/restmachine/cloudapi/compute/delete"
|
||||||
@@ -271,14 +272,14 @@ type ComputeRecord struct {
|
|||||||
SnapSets []SnapSetRecord `json:"snapSets"`
|
SnapSets []SnapSetRecord `json:"snapSets"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
// Tags []string `json:"tags"` // Tags were reworked since DECORT 3.7.1
|
// Tags []string `json:"tags"` // Tags were reworked since DECORT 3.7.1
|
||||||
TechStatus string `json:"techStatus"`
|
TechStatus string `json:"techStatus"`
|
||||||
TotalDiskSize int `json:"totalDiskSize"`
|
TotalDiskSize int `json:"totalDiskSize"`
|
||||||
UpdatedBy string `json:"updatedBy"`
|
UpdatedBy string `json:"updatedBy"`
|
||||||
UpdateTime uint64 `json:"updateTime"`
|
UpdateTime uint64 `json:"updateTime"`
|
||||||
UserManaged bool `json:"userManaged"`
|
UserManaged bool `json:"userManaged"`
|
||||||
Vgpus []int `json:"vgpus"`
|
Vgpus []int `json:"vgpus"`
|
||||||
VinsConnected int `json:"vinsConnected"`
|
VinsConnected int `json:"vinsConnected"`
|
||||||
VirtualImageID int `json:"virtualImageId"`
|
VirtualImageID int `json:"virtualImageId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const ComputeListAPI = "/restmachine/cloudapi/compute/list"
|
const ComputeListAPI = "/restmachine/cloudapi/compute/list"
|
||||||
@@ -302,7 +303,7 @@ type DiskRecord struct {
|
|||||||
// ACLs `json:"ACL"` - it is a dictionary, special parsing required
|
// ACLs `json:"ACL"` - it is a dictionary, special parsing required
|
||||||
// was - Acl map[string]string `json:"acl"`
|
// was - Acl map[string]string `json:"acl"`
|
||||||
AccountID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
AccountName string `json:"accountName"` // NOTE: absent from compute/get output
|
AccountName string `json:"accountName"` // NOTE: absent from compute/get output
|
||||||
BootPartition int `json:"bootPartition"`
|
BootPartition int `json:"bootPartition"`
|
||||||
CreatedTime uint64 `json:"creationTime"`
|
CreatedTime uint64 `json:"creationTime"`
|
||||||
DeletedTime uint64 `json:"deletionTime"`
|
DeletedTime uint64 `json:"deletionTime"`
|
||||||
@@ -325,7 +326,7 @@ type DiskRecord struct {
|
|||||||
PurgeTime uint64 `json:"purgeTime"`
|
PurgeTime uint64 `json:"purgeTime"`
|
||||||
// Role string `json:"role"`
|
// Role string `json:"role"`
|
||||||
SepType string `json:"sepType"`
|
SepType string `json:"sepType"`
|
||||||
SepID int `json:"sepId"` // NOTE: absent from compute/get output
|
SepID int `json:"sepId"` // NOTE: absent from compute/get output
|
||||||
SizeMax int `json:"sizeMax"`
|
SizeMax int `json:"sizeMax"`
|
||||||
SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space
|
SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space
|
||||||
Snapshots []SnapshotRecord `json:"snapshots"`
|
Snapshots []SnapshotRecord `json:"snapshots"`
|
||||||
@@ -376,14 +377,14 @@ type ComputeGetResp struct {
|
|||||||
SnapSets []SnapSetRecord `json:"snapSets"`
|
SnapSets []SnapSetRecord `json:"snapSets"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
// Tags []string `json:"tags"` // Tags were reworked since DECORT 3.7.1
|
// Tags []string `json:"tags"` // Tags were reworked since DECORT 3.7.1
|
||||||
TechStatus string `json:"techStatus"`
|
TechStatus string `json:"techStatus"`
|
||||||
TotalDiskSize int `json:"totalDiskSize"`
|
TotalDiskSize int `json:"totalDiskSize"`
|
||||||
UpdatedBy string `json:"updatedBy"`
|
UpdatedBy string `json:"updatedBy"`
|
||||||
UpdateTime uint64 `json:"updateTime"`
|
UpdateTime uint64 `json:"updateTime"`
|
||||||
UserManaged bool `json:"userManaged"`
|
UserManaged bool `json:"userManaged"`
|
||||||
Vgpus []int `json:"vgpus"`
|
Vgpus []int `json:"vgpus"`
|
||||||
VinsConnected int `json:"vinsConnected"`
|
VinsConnected int `json:"vinsConnected"`
|
||||||
VirtualImageID int `json:"virtualImageId"`
|
VirtualImageID int `json:"virtualImageId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -468,11 +469,12 @@ const ComputePfwDelAPI = "/restmachine/cloudapi/compute/pfwDel"
|
|||||||
// structures related to /cloudapi/compute/net Attach/Detach API
|
// structures related to /cloudapi/compute/net Attach/Detach API
|
||||||
//
|
//
|
||||||
type ComputeNetMgmtRecord struct { // used to "cache" network specs when preparing to manage compute networks
|
type ComputeNetMgmtRecord struct { // used to "cache" network specs when preparing to manage compute networks
|
||||||
ID int
|
ID int
|
||||||
Type string
|
Type string
|
||||||
IPAddress string
|
IPAddress string
|
||||||
MAC string
|
MAC string
|
||||||
}
|
}
|
||||||
|
|
||||||
const ComputeNetAttachAPI = "/restmachine/cloudapi/compute/netAttach"
|
const ComputeNetAttachAPI = "/restmachine/cloudapi/compute/netAttach"
|
||||||
|
|
||||||
const ComputeNetDetachAPI = "/restmachine/cloudapi/compute/netDetach"
|
const ComputeNetDetachAPI = "/restmachine/cloudapi/compute/netDetach"
|
||||||
@@ -512,52 +514,52 @@ const DisksRenameAPI = "/restmachine/cloudapi/disks/rename"
|
|||||||
//
|
//
|
||||||
const DisksDeleteAPI = "/restmachine/cloudapi/disks/delete"
|
const DisksDeleteAPI = "/restmachine/cloudapi/disks/delete"
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ViNS structures
|
// ViNS structures
|
||||||
//
|
//
|
||||||
|
|
||||||
// this is the structure of the element in the list returned by vins/search API
|
// this is the structure of the element in the list returned by vins/search API
|
||||||
type VinsSearchRecord struct {
|
type VinsSearchRecord struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
IPCidr string `json:"network"`
|
IPCidr string `json:"network"`
|
||||||
VxLanID int `json:"vxlanId"`
|
VxLanID int `json:"vxlanId"`
|
||||||
ExternalIP string `json:"externalIP"`
|
ExternalIP string `json:"externalIP"`
|
||||||
AccountID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
AccountName string `json:"accountName"`
|
AccountName string `json:"accountName"`
|
||||||
RgID int `json:"rgId"`
|
RgID int `json:"rgId"`
|
||||||
RgName string `json:"rgName"`
|
RgName string `json:"rgName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const VinsSearchAPI = "/restmachine/cloudapi/vins/search"
|
const VinsSearchAPI = "/restmachine/cloudapi/vins/search"
|
||||||
|
|
||||||
type VinsSearchResp []VinsSearchRecord
|
type VinsSearchResp []VinsSearchRecord
|
||||||
|
|
||||||
type VnfRecord struct {
|
type VnfRecord struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
AccountID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
Type string `json:"type"` // "DHCP", "NAT", "GW" etc
|
Type string `json:"type"` // "DHCP", "NAT", "GW" etc
|
||||||
Config map[string]interface{} `json:"config"` // NOTE: VNF specs vary by VNF type
|
Config map[string]interface{} `json:"config"` // NOTE: VNF specs vary by VNF type
|
||||||
}
|
}
|
||||||
|
|
||||||
type VnfGwConfigRecord struct { // describes GW VNF config structure inside ViNS, as returned by API vins/get
|
type VnfGwConfigRecord struct { // describes GW VNF config structure inside ViNS, as returned by API vins/get
|
||||||
ExtNetID int `json:"ext_net_id"`
|
ExtNetID int `json:"ext_net_id"`
|
||||||
ExtNetIP string `json:"ext_net_ip"`
|
ExtNetIP string `json:"ext_net_ip"`
|
||||||
ExtNetMask int `json:"ext_net_mask"`
|
ExtNetMask int `json:"ext_net_mask"`
|
||||||
DefaultGW string `json:"default_gw"`
|
DefaultGW string `json:"default_gw"`
|
||||||
}
|
}
|
||||||
type VinsRecord struct { // represents part of the response from API vins/get
|
type VinsRecord struct { // represents part of the response from API vins/get
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
IPCidr string `json:"network"`
|
IPCidr string `json:"network"`
|
||||||
VxLanID int `json:"vxlanId"`
|
VxLanID int `json:"vxlanId"`
|
||||||
ExternalIP string `json:"externalIP"`
|
ExternalIP string `json:"externalIP"`
|
||||||
AccountID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
AccountName string `json:"accountName"`
|
AccountName string `json:"accountName"`
|
||||||
RgID int `json:"rgid"`
|
RgID int `json:"rgid"`
|
||||||
RgName string `json:"rgName"`
|
RgName string `json:"rgName"`
|
||||||
VNFs map[string]VnfRecord `json:"vnfs"`
|
VNFs map[string]VnfRecord `json:"vnfs"`
|
||||||
Desc string `json:"desc"`
|
Desc string `json:"desc"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const VinsGetAPI = "/restmachine/cloudapi/vins/get"
|
const VinsGetAPI = "/restmachine/cloudapi/vins/get"
|
||||||
@@ -572,13 +574,13 @@ const VinsDeleteAPI = "/restmachine/cloudapi/vins/delete"
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Grid ID structures
|
// Grid ID structures
|
||||||
//
|
//
|
||||||
type LocationRecord struct {
|
type LocationRecord struct {
|
||||||
GridID int `json:"gid"`
|
GridID int `json:"gid"`
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
LocationCode string `json:"locationCode"`
|
LocationCode string `json:"locationCode"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Flag string `json:"flag"`
|
Flag string `json:"flag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const LocationsListAPI = "/restmachine/cloudapi/locations/list" // Returns list of GridRecord on success
|
const LocationsListAPI = "/restmachine/cloudapi/locations/list" // Returns list of GridRecord on success
|
||||||
|
|||||||
@@ -50,15 +50,15 @@ func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||||
// we assume all mandatory parameters it takes to create a comptue instance are properly
|
// we assume all mandatory parameters it takes to create a comptue instance are properly
|
||||||
// specified - we rely on schema "Required" attributes to let Terraform validate them for us
|
// specified - we rely on schema "Required" attributes to let Terraform validate them for us
|
||||||
|
|
||||||
log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int))
|
log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
|
|
||||||
// create basic Compute (i.e. without extra disks and network connections - those will be attached
|
// create basic Compute (i.e. without extra disks and network connections - those will be attached
|
||||||
// by subsequent individual API calls).
|
// by subsequent individual API calls).
|
||||||
// creating Compute is a multi-step workflow, which may fail at some step, so we use "partial" feature of Terraform
|
// creating Compute is a multi-step workflow, which may fail at some step, so we use "partial" feature of Terraform
|
||||||
d.Partial(true)
|
d.Partial(true)
|
||||||
controller := m.(*ControllerCfg)
|
controller := m.(*ControllerCfg)
|
||||||
urlValues := &url.Values{}
|
urlValues := &url.Values{}
|
||||||
urlValues.Add("rgId", fmt.Sprintf("%d", d.Get("rg_id").(int)))
|
urlValues.Add("rgId", fmt.Sprintf("%d", d.Get("rg_id").(int)))
|
||||||
@@ -68,32 +68,32 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
|||||||
urlValues.Add("imageId", fmt.Sprintf("%d", d.Get("image_id").(int)))
|
urlValues.Add("imageId", fmt.Sprintf("%d", d.Get("image_id").(int)))
|
||||||
urlValues.Add("bootDisk", fmt.Sprintf("%d", d.Get("boot_disk_size").(int)))
|
urlValues.Add("bootDisk", fmt.Sprintf("%d", d.Get("boot_disk_size").(int)))
|
||||||
urlValues.Add("netType", "NONE") // at the 1st step create isolated compute
|
urlValues.Add("netType", "NONE") // at the 1st step create isolated compute
|
||||||
urlValues.Add("start", "0") // at the 1st step create compute in a stopped state
|
urlValues.Add("start", "0") // at the 1st step create compute in a stopped state
|
||||||
|
|
||||||
argVal, argSet := d.GetOk("description")
|
argVal, argSet := d.GetOk("description")
|
||||||
if argSet {
|
if argSet {
|
||||||
urlValues.Add("desc", argVal.(string))
|
urlValues.Add("desc", argVal.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
sshKeysVal, sshKeysSet := d.GetOk("ssh_keys")
|
sshKeysVal, sshKeysSet := d.GetOk("ssh_keys")
|
||||||
if sshKeysSet {
|
if sshKeysSet {
|
||||||
// process SSH Key settings and set API values accordingly
|
// process SSH Key settings and set API values accordingly
|
||||||
log.Debugf("resourceComputeCreate: calling makeSshKeysArgString to setup SSH keys for guest login(s)")
|
log.Debugf("resourceComputeCreate: calling makeSshKeysArgString to setup SSH keys for guest login(s)")
|
||||||
urlValues.Add("userdata", makeSshKeysArgString(sshKeysVal.([]interface{})))
|
urlValues.Add("userdata", makeSshKeysArgString(sshKeysVal.([]interface{})))
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
computeCreateAPI := KvmX86CreateAPI
|
computeCreateAPI := KvmX86CreateAPI
|
||||||
arch := d.Get("arch").(string)
|
driver := d.Get("driver").(string)
|
||||||
if arch == "KVM_PPC" {
|
if driver == "KVM_PPC" {
|
||||||
computeCreateAPI = KvmPPCCreateAPI
|
computeCreateAPI = KvmPPCCreateAPI
|
||||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC")
|
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC")
|
||||||
} else { // note that we do not validate arch value for explicit "KVM_X86" here
|
} else { // note that we do not validate arch value for explicit "KVM_X86" here
|
||||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
|
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
|
||||||
}
|
}
|
||||||
|
|
||||||
argVal, argSet = d.GetOk("cloud_init")
|
argVal, argSet = d.GetOk("cloud_init")
|
||||||
if argSet {
|
if argSet {
|
||||||
// userdata must not be empty string and must not be a reserved keyword "applied"
|
// userdata must not be empty string and must not be a reserved keyword "applied"
|
||||||
userdata := argVal.(string)
|
userdata := argVal.(string)
|
||||||
@@ -101,7 +101,7 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
|||||||
urlValues.Add("userdata", userdata)
|
urlValues.Add("userdata", userdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apiResp, err := controller.decortAPICall("POST", computeCreateAPI, urlValues)
|
apiResp, err := controller.decortAPICall("POST", computeCreateAPI, urlValues)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -117,16 +117,16 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
|||||||
d.SetPartial("image_id")
|
d.SetPartial("image_id")
|
||||||
d.SetPartial("boot_disk_size")
|
d.SetPartial("boot_disk_size")
|
||||||
/*
|
/*
|
||||||
if sshKeysSet {
|
if sshKeysSet {
|
||||||
d.SetPartial("ssh_keys")
|
d.SetPartial("ssh_keys")
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", compId, d.Get("name").(string))
|
log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", compId, d.Get("name").(string))
|
||||||
|
|
||||||
// Configure data disks if any
|
// Configure data disks if any
|
||||||
extraDisksOk := true
|
extraDisksOk := true
|
||||||
argVal, argSet = d.GetOk("extra_disks")
|
argVal, argSet = d.GetOk("extra_disks")
|
||||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||||
// urlValues.Add("desc", argVal.(string))
|
// urlValues.Add("desc", argVal.(string))
|
||||||
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
|
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
|
||||||
@@ -142,8 +142,8 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
|||||||
|
|
||||||
// Configure external networks if any
|
// Configure external networks if any
|
||||||
netsOk := true
|
netsOk := true
|
||||||
argVal, argSet = d.GetOk("network")
|
argVal, argSet = d.GetOk("network")
|
||||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||||
log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len())
|
log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len())
|
||||||
err = controller.utilityComputeNetworksConfigure(d, false) // do_delta=false, as we are working on a new compute
|
err = controller.utilityComputeNetworksConfigure(d, false) // do_delta=false, as we are working on a new compute
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -161,23 +161,25 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
|||||||
d.Partial(false)
|
d.Partial(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
|
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
|
||||||
// now we need to start it before we report the sequence complete
|
// now we need to start it before we report the sequence complete
|
||||||
reqValues := &url.Values{}
|
if d.Get("started").(bool) {
|
||||||
reqValues.Add("computeId", fmt.Sprintf("%d", compId))
|
reqValues := &url.Values{}
|
||||||
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId)
|
reqValues.Add("computeId", fmt.Sprintf("%d", compId))
|
||||||
apiResp, err = controller.decortAPICall("POST", ComputeStartAPI, reqValues)
|
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId)
|
||||||
if err != nil {
|
apiResp, err = controller.decortAPICall("POST", ComputeStartAPI, reqValues)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", compId, d.Get("name").(string))
|
log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", compId, d.Get("name").(string))
|
||||||
|
|
||||||
// We may reuse dataSourceComputeRead here as we maintain similarity
|
// We may reuse dataSourceComputeRead here as we maintain similarity
|
||||||
// between Compute resource and Compute data source schemas
|
// between Compute resource and Compute data source schemas
|
||||||
// Compute read function will also update resource ID on success, so that Terraform
|
// Compute read function will also update resource ID on success, so that Terraform
|
||||||
// will know the resource exists
|
// will know the resource exists
|
||||||
return dataSourceComputeRead(d, m)
|
return dataSourceComputeRead(d, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceComputeRead(d *schema.ResourceData, m interface{}) error {
|
func resourceComputeRead(d *schema.ResourceData, m interface{}) error {
|
||||||
@@ -209,11 +211,12 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
|||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
controller := m.(*ControllerCfg)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1. Resize CPU/RAM
|
1. Resize CPU/RAM
|
||||||
2. Resize (grow) boot disk
|
2. Resize (grow) boot disk
|
||||||
3. Update extra disks
|
3. Update extra disks
|
||||||
4. Update networks
|
4. Update networks
|
||||||
|
5. Start/stop
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 1. Resize CPU/RAM
|
// 1. Resize CPU/RAM
|
||||||
@@ -230,7 +233,7 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
|||||||
} else {
|
} else {
|
||||||
params.Add("cpu", "0") // no change to CPU allocation
|
params.Add("cpu", "0") // no change to CPU allocation
|
||||||
}
|
}
|
||||||
|
|
||||||
oldRam, newRam := d.GetChange("ram")
|
oldRam, newRam := d.GetChange("ram")
|
||||||
if oldRam.(int) != newRam.(int) {
|
if oldRam.(int) != newRam.(int) {
|
||||||
params.Add("ram", fmt.Sprintf("%d", newRam.(int)))
|
params.Add("ram", fmt.Sprintf("%d", newRam.(int)))
|
||||||
@@ -241,8 +244,8 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
|||||||
|
|
||||||
if doUpdate {
|
if doUpdate {
|
||||||
log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d",
|
log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d",
|
||||||
oldCpu.(int), newCpu.(int),
|
oldCpu.(int), newCpu.(int),
|
||||||
oldRam.(int), newRam.(int))
|
oldRam.(int), newRam.(int))
|
||||||
_, err := controller.decortAPICall("POST", ComputeResizeAPI, params)
|
_, err := controller.decortAPICall("POST", ComputeResizeAPI, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -251,14 +254,14 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
|||||||
d.SetPartial("ram")
|
d.SetPartial("ram")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Resize (grow) Boot disk
|
// 2. Resize (grow) Boot disk
|
||||||
oldSize, newSize := d.GetChange("boot_disk_size")
|
oldSize, newSize := d.GetChange("boot_disk_size")
|
||||||
if oldSize.(int) < newSize.(int) {
|
if oldSize.(int) < newSize.(int) {
|
||||||
bdsParams := &url.Values{}
|
bdsParams := &url.Values{}
|
||||||
bdsParams.Add("diskId", fmt.Sprintf("%d", d.Get("boot_disk_id").(int)))
|
bdsParams.Add("diskId", fmt.Sprintf("%d", d.Get("boot_disk_id").(int)))
|
||||||
bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
||||||
log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d",
|
log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d",
|
||||||
d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int))
|
d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int))
|
||||||
_, err := controller.decortAPICall("POST", DisksResizeAPI, params)
|
_, err := controller.decortAPICall("POST", DisksResizeAPI, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -284,17 +287,32 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
|||||||
d.SetPartial("network")
|
d.SetPartial("network")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.HasChange("started") {
|
||||||
|
params := &url.Values{}
|
||||||
|
params.Add("computeId", d.Id())
|
||||||
|
if d.Get("started").(bool) {
|
||||||
|
if _, err := controller.decortAPICall("POST", ComputeStartAPI, params); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := controller.decortAPICall("POST", ComputeStopAPI, params); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.SetPartial("started")
|
||||||
|
}
|
||||||
|
|
||||||
d.Partial(false)
|
d.Partial(false)
|
||||||
|
|
||||||
// we may reuse dataSourceComputeRead here as we maintain similarity
|
// we may reuse dataSourceComputeRead here as we maintain similarity
|
||||||
// between Compute resource and Compute data source schemas
|
// between Compute resource and Compute data source schemas
|
||||||
return dataSourceComputeRead(d, m)
|
return dataSourceComputeRead(d, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
||||||
// NOTE: this function destroys target Compute instance "permanently", so
|
// NOTE: this function destroys target Compute instance "permanently", so
|
||||||
// there is no way to restore it.
|
// there is no way to restore it.
|
||||||
// If compute being destroyed has some extra disks attached, they are
|
// If compute being destroyed has some extra disks attached, they are
|
||||||
// detached from the compute
|
// detached from the compute
|
||||||
log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d",
|
log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d",
|
||||||
d.Get("name").(string), d.Get("rg_id").(int))
|
d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
@@ -312,7 +330,7 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
|||||||
log.Debugf("resourceComputeDelete: ready to unmarshal string %s", compFacts)
|
log.Debugf("resourceComputeDelete: ready to unmarshal string %s", compFacts)
|
||||||
err = json.Unmarshal([]byte(compFacts), &model)
|
err = json.Unmarshal([]byte(compFacts), &model)
|
||||||
if err == nil && len(model.Disks) > 0 {
|
if err == nil && len(model.Disks) > 0 {
|
||||||
// prepare to detach data disks from compute - do it only if compFacts unmarshalled
|
// prepare to detach data disks from compute - do it only if compFacts unmarshalled
|
||||||
// properly and the resulting model contains non-empty Disks list
|
// properly and the resulting model contains non-empty Disks list
|
||||||
for _, diskFacts := range model.Disks {
|
for _, diskFacts := range model.Disks {
|
||||||
if diskFacts.Type == "B" {
|
if diskFacts.Type == "B" {
|
||||||
@@ -338,7 +356,7 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
|||||||
params.Add("computeId", d.Id())
|
params.Add("computeId", d.Id())
|
||||||
params.Add("permanently", "1")
|
params.Add("permanently", "1")
|
||||||
// TODO: this is for the upcoming API update - params.Add("detachdisks", "1")
|
// TODO: this is for the upcoming API update - params.Add("detachdisks", "1")
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", ComputeDeleteAPI, params)
|
_, err = controller.decortAPICall("POST", ComputeDeleteAPI, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -398,13 +416,13 @@ func resourceCompute() *schema.Resource {
|
|||||||
Description: "ID of the resource group where this compute should be deployed.",
|
Description: "ID of the resource group where this compute should be deployed.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"arch": {
|
"driver": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
StateFunc: stateFuncToUpper,
|
StateFunc: stateFuncToUpper,
|
||||||
ValidateFunc: validation.StringInSlice([]string{"KVM_X86", "KVM_PPC"}, false), // observe case while validating
|
ValidateFunc: validation.StringInSlice([]string{"KVM_X86", "KVM_PPC"}, false), // observe case while validating
|
||||||
Description: "Hardware architecture of this compute instance.",
|
Description: "Hardware architecture of this compute instance.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"cpu": {
|
"cpu": {
|
||||||
@@ -422,16 +440,16 @@ func resourceCompute() *schema.Resource {
|
|||||||
},
|
},
|
||||||
|
|
||||||
"image_id": {
|
"image_id": {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ValidateFunc: validation.IntAtLeast(1),
|
ValidateFunc: validation.IntAtLeast(1),
|
||||||
Description: "ID of the OS image to base this compute instance on.",
|
Description: "ID of the OS image to base this compute instance on.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"boot_disk_size": {
|
"boot_disk_size": {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.",
|
Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.",
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -456,15 +474,15 @@ func resourceCompute() *schema.Resource {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
"ssh_keys": {
|
"ssh_keys": {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
MaxItems: MaxSshKeysPerCompute,
|
MaxItems: MaxSshKeysPerCompute,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: sshSubresourceSchemaMake(),
|
Schema: sshSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "SSH keys to authorize on this compute instance.",
|
||||||
},
|
},
|
||||||
Description: "SSH keys to authorize on this compute instance.",
|
|
||||||
},
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"description": {
|
"description": {
|
||||||
@@ -473,13 +491,12 @@ func resourceCompute() *schema.Resource {
|
|||||||
Description: "Optional text description of this compute instance.",
|
Description: "Optional text description of this compute instance.",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"cloud_init": {
|
"cloud_init": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Default: "applied",
|
Default: "applied",
|
||||||
DiffSuppressFunc: cloudInitDiffSupperss,
|
DiffSuppressFunc: cloudInitDiffSupperss,
|
||||||
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
|
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
|
||||||
},
|
},
|
||||||
|
|
||||||
// The rest are Compute properties, which are "computed" once it is created
|
// The rest are Compute properties, which are "computed" once it is created
|
||||||
@@ -516,37 +533,44 @@ func resourceCompute() *schema.Resource {
|
|||||||
Description: "Guest OS users provisioned on this compute instance.",
|
Description: "Guest OS users provisioned on this compute instance.",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"started": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Description: "Is compute started.",
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
"disks": {
|
"disks": {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
||||||
|
},
|
||||||
|
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
||||||
},
|
},
|
||||||
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
|
||||||
},
|
|
||||||
|
|
||||||
"interfaces": {
|
"interfaces": {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: interfaceSubresourceSchemaMake(),
|
Schema: interfaceSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Specification for the virtual NICs configured on this compute instance.",
|
||||||
},
|
},
|
||||||
Description: "Specification for the virtual NICs configured on this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
"status": {
|
"status": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "Current model status of this compute instance.",
|
Description: "Current model status of this compute instance.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"tech_status": {
|
"tech_status": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "Current technical status of this compute instance.",
|
Description: "Current technical status of this compute instance.",
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user