Code adjustments during the 1st debug phase

rc-1.0
Sergey Shubin svs1370 4 years ago
parent f8611fec30
commit 0179a1ef45

1
.gitignore vendored

@ -1 +1,2 @@
decort/vendor/
terraform-provider-decort*

@ -84,13 +84,13 @@ func dataSourceAccount() *schema.Resource {
Description: "Name of the account. Names are case sensitive and unique.",
},
"account_id": &schema.Schema{
"account_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the account. If account ID is specified, then account name is ignored.",
},
"status": &schema.Schema{
"status": {
Type: schema.TypeString,
Computed: true,
Description: "Current status of the account.",

@ -35,11 +35,53 @@ import (
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
// 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
length := len(disks)
log.Debugf("parseComputeDisksToExtraDisks: called for %d disks", length)
if length == 1 && disks[0].Type == "B" {
// 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
length = 0
}
result := make([]interface{}, length)
if length == 0 {
return result
}
idx := 0
for _, value := range disks {
if value.Type == "B" {
// skip boot disk when iterating over the list of disks
continue
}
result[idx] = value.ID
idx++
}
return result
}
func parseComputeDisks(disks []DiskRecord) []interface{} {
// return value was designed to d.Set("disks",) item of dataSourceCompute schema
length := len(disks)
log.Debugf("parseComputeDisks: called for %d disks", length)
/*
if length == 1 && disks[0].Type == "B" {
// 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
length = 0
}
*/
result := make([]interface{}, length)
if length == 0 {
return result
}
@ -47,6 +89,12 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
elem := make(map[string]interface{})
for i, value := range disks {
/*
if value.Type == "B" {
// skip boot disk when parsing the list of disks
continue
}
*/
// keys in this map should correspond to the Schema definition
// as returned by dataSourceDiskSchemaMake()
elem["name"] = value.Name
@ -66,14 +114,57 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
result[i] = elem
}
return result // this result will be used to d.Set("disks",) item of dataSourceCompute schema
return result
}
func parseBootDiskSize(disks []DiskRecord) int {
// this return value will be used to d.Set("boot_disk_size",) item of dataSourceCompute schema
if len(disks) == 0 {
return 0
}
for _, value := range disks {
if value.Type == "B" {
return value.SizeMax
}
}
return 0
}
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
// return value will be used to d.Set("networks",) item of dataSourceCompute schema
length := len(ifaces)
log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length)
result := make([]interface{}, length)
if length == 0 {
return result
}
elem := make(map[string]interface{})
for i, value := range ifaces {
// Keys in this map should correspond to the Schema definition
// as returned by networkSubresourceSchemaMake()
elem["net_id"] = value.NetID
elem["net_type"] = value.NetType
elem["ip_address"] = value.IPAddress
result[i] = elem
}
return result
}
func parseComputeInterfaces(ifaces []InterfaceRecord) []interface{} {
// return value was designed to d.Set("interfaces",) item of dataSourceCompute schema
length := len(ifaces)
log.Debugf("parseComputeInterfaces: called for %d ifaces", length)
result := make([]interface{}, length)
if length == 0 {
return result
}
@ -93,7 +184,7 @@ func parseComputeInterfaces(ifaces []InterfaceRecord) []interface{} {
elem["connection_id"] = value.ConnID
elem["connection_type"] = value.ConnType
/* TODO: add code to read in quota
/* TODO: add code to parse QoS
qos_schema := interfaceQosSubresourceSchemaMake()
qos_schema.Set("egress_rate", value.QOS.ERate)
qos_schema.Set("ingress_rate", value.QOS.InRate)
@ -104,7 +195,7 @@ func parseComputeInterfaces(ifaces []InterfaceRecord) []interface{} {
result[i] = elem
}
return result // this result will be used to d.Set("interfaces",) item of dataSourceCompute schema
return result
}
func flattenCompute(d *schema.ResourceData, compFacts string) error {
@ -132,7 +223,8 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
d.Set("arch", model.Arch)
d.Set("cpu", model.Cpu)
d.Set("ram", model.Ram)
d.Set("boot_disk_size", model.BootDiskSize)
// d.Set("boot_disk_size", model.BootDiskSize) - bootdiskSize key in API compute/get is always zero, so we set boot_disk_size in another way
d.Set("boot_disk_size", parseBootDiskSize(model.Disks))
d.Set("image_id", model.ImageID)
d.Set("description", model.Desc)
d.Set("status", model.Status)
@ -140,14 +232,14 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
if len(model.Disks) > 0 {
log.Debugf("flattenCompute: calling parseComputeDisks for %d disks", len(model.Disks))
if err = d.Set("disks", parseComputeDisks(model.Disks)); err != nil {
if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil {
return err
}
}
if len(model.Interfaces) > 0 {
log.Debugf("flattenCompute: calling parseComputeInterfaces for %d interfaces", len(model.Interfaces))
if err = d.Set("interfaces", parseComputeInterfaces(model.Interfaces)); err != nil {
if err = d.Set("networks", parseComputeInterfacesToNetworks(model.Interfaces)); err != nil {
return err
}
}
@ -258,6 +350,17 @@ func dataSourceCompute() *schema.Resource {
Description: "This compute instance boot disk size in GB.",
},
"extra_disks": {
Type: schema.TypeList,
Computed: true,
MaxItems: MaxExtraDisksPerCompute,
Elem: &schema.Schema {
Type: schema.TypeInt,
},
Description: "IDs of the extra disks attached to this compute.",
},
/*
"disks": {
Type: schema.TypeList,
Computed: true,
@ -266,16 +369,19 @@ func dataSourceCompute() *schema.Resource {
},
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
},
*/
"guest_logins": {
"networks": {
Type: schema.TypeList,
Computed: true,
Optional: true,
MaxItems: MaxNetworksPerCompute,
Elem: &schema.Resource{
Schema: loginsSubresourceSchemaMake(),
Schema: networkSubresourceSchemaMake(),
},
Description: "Details about the guest OS users provisioned together with this compute instance.",
Description: "Networks this compute is attached to.",
},
/*
"interfaces": {
Type: schema.TypeList,
Computed: true,
@ -284,6 +390,16 @@ func dataSourceCompute() *schema.Resource {
},
Description: "Specification for the virtual NICs configured on this compute instance.",
},
*/
"guest_logins": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: loginsSubresourceSchemaMake(),
},
Description: "Details about the guest OS users provisioned together with this compute instance.",
},
"description": {
Type: schema.TypeString,

@ -39,7 +39,7 @@ func flattenDisk(d *schema.ResourceData, disk_facts string) error {
// This function expects disk_facts string to contain a response from disks/get API
//
// NOTE: this function modifies ResourceData argument - as such it should never be called
// from resourceDiskExists(...) method
// from resourceDiskExists(...) method. Use utilityDiskCheckPresence instead.
model := DiskRecord{}
log.Debugf("flattenDisk: ready to unmarshal string %q", disk_facts)
err := json.Unmarshal([]byte(disk_facts), &model)
@ -153,7 +153,7 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema {
*/
"sep_id": {
Type: schema.TypeString,
Type: schema.TypeInt,
Computed: true,
Description: "Storage end-point provider serving this disk.",
},

@ -101,31 +101,31 @@ func dataSourceResgroup() *schema.Resource {
Description: "Name of the resource group. Names are case sensitive and unique within the context of an account.",
},
"rg_id": &schema.Schema{
"rg_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the resource group. If this ID is specified, then resource group name is ignored.",
},
"account_name": &schema.Schema{
"account_name": {
Type: schema.TypeString,
Optional: true,
Description: "Name of the account, which this resource group belongs to.",
},
"account_id": &schema.Schema{
"account_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the account, which this resource group belongs to. If account ID is specified, then account name is ignored.",
},
"description": &schema.Schema{
"description": {
Type: schema.TypeString,
Computed: true,
Description: "User-defined text description of this resource group.",
},
"grid_id": &schema.Schema{
"grid_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Unique ID of the grid, where this resource group is deployed.",
@ -133,7 +133,7 @@ func dataSourceResgroup() *schema.Resource {
"quota": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: quotaRgSubresourceSchemaMake(), // this is a dictionary
@ -147,13 +147,13 @@ func dataSourceResgroup() *schema.Resource {
Description: "Current status of this resource group.",
},
"def_net_type": &schema.Schema{
"def_net_type": {
Type: schema.TypeString,
Computed: true,
Description: "Type of the default network for this resource group.",
},
"def_net_id": &schema.Schema{
"def_net_id": {
Type: schema.TypeInt,
Computed: true,
Description: "ID of the default network for this resource group (if any).",

@ -89,11 +89,12 @@ func interfaceSubresourceSchemaMake() map[string]*schema.Schema {
},
"qos": {
Computed: true,
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: interfaceQosSubresourceSchemaMake(),
},
Description: "Details about the guest OS users provisioned together with this compute instance.",
Description: "QoS settings for this interface.",
},
}

@ -105,12 +105,12 @@ type ResgroupUpdateParam struct {
// structures related to /cloudapi/rg/get API call
//
type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get
Cpu int `json:"CU_C"` // CPU count in pcs
Ram int `json:"CU_M"` // RAM volume in MB
Disk int `json:"CU_D"` // Disk capacity in GB
ExtIPs int `json:"CU_I"` // Ext IPs count
ExtTraffic int `json:"CU_NP"` // Ext network traffic
GpuUnits int `json:"gpu_units"` // GPU count
Cpu int `json:"CU_C"` // CPU count in pcs
Ram float32 `json:"CU_M"` // RAM volume in MB, it is STILL reported as FLOAT
Disk int `json:"CU_D"` // Disk capacity in GB
ExtIPs int `json:"CU_I"` // Ext IPs count
ExtTraffic int `json:"CU_NP"` // Ext network traffic
GpuUnits int `json:"gpu_units"` // GPU count
}
type ResourceRecord struct { // this is how actual usage is reported by /api/.../rg/get
@ -245,7 +245,7 @@ type ComputeRecord struct {
AccountName string `json:"accountName"`
ACLs []UserAclRecord `json:"acl"`
Arch string `json:"arch"`
BootDiskSize int `json:"bootdiskSize"`
BootDiskSize int `json:"bootdiskSize"` // NOTE: this key is always 0 in compute/get API response
CloneReference int `json:"cloneReference"`
Clones []int `json:"clones"`
Cpus int `json:"cpus"`
@ -258,7 +258,7 @@ type ComputeRecord struct {
GridID int `json:"gid"`
ID uint `json:"id"`
ImageID int `json:"imageId"`
Interfaces []InterfaceRecord `json:"interfaces`
Interfaces []InterfaceRecord `json:"interfaces"`
LockStatus string `json:"lockStatus"`
ManagerID int `json:"managerId"`
Name string `json:"name"`
@ -297,7 +297,7 @@ type DiskRecord struct {
// ACLs `json:"ACL"` - it is a dictionary, special parsing required
// was - Acl map[string]string `json:"acl"`
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"`
CreatedTime uint64 `json:"creationTime"`
DeletedTime uint64 `json:"deletionTime"`
@ -320,7 +320,7 @@ type DiskRecord struct {
PurgeTime uint64 `json:"purgeTime"`
// Role string `json:"role"`
SepType string `json:"sepType"`
SepID int `json:"sepid"`
SepID int `json:"sepid"` // NOTE: absent from compute/get output
SizeMax int `json:"sizeMax"`
SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space
Snapshots []SnapshotRecord `json:"snapshots"`

@ -32,19 +32,19 @@ import (
func networkSubresourceSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"net_type": &schema.Schema{
"net_type": {
Type: schema.TypeString,
Required: true,
Description: "Type of the network for this connection, either EXTNET or VINS.",
},
"net_id": &schema.Schema{
"net_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of the network for this connection.",
},
"ipaddr": &schema.Schema{
"ip_address": {
Type: schema.TypeString,
Optional: true,
Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.",

@ -99,7 +99,7 @@ func Provider() *schema.Provider {
ResourcesMap: map[string]*schema.Resource{
"decort_resgroup": resourceResgroup(),
// "decort_kvmvm": resourceCompute(),
"decort_kvmvm": resourceCompute(),
// "decort_disk": resourceDisk(),
// "decort_vins": resourceVins(),
// "decort_pfw": resourcePfw(),
@ -110,7 +110,7 @@ func Provider() *schema.Provider {
"decort_resgroup": dataSourceResgroup(),
"decort_kvmvm": dataSourceCompute(),
"decort_image": dataSourceImage(),
"decort_disk": dataSourceDisk(),
// "decort_disk": dataSourceDisk(),
// "decort_vins": dataSourceVins(),
// "decort_pfw": dataSourcePfw(),
},

@ -31,7 +31,7 @@ import (
func makeQuotaRecord(arg_list []interface{}) (QuotaRecord, int) {
quota := QuotaRecord{
Cpu: -1,
Ram: -1,
Ram: -1.,
Disk: -1,
ExtTraffic: -1,
ExtIPs: -1,
@ -48,7 +48,7 @@ func makeQuotaRecord(arg_list []interface{}) (QuotaRecord, int) {
}
if subres_data["ram"].(int) > 0 {
quota.Ram = subres_data["ram"].(int) // RAM volume in MB
quota.Ram = subres_data["ram"].(float32) // RAM volume in MB, as float!
}
if subres_data["ext_traffic"].(int) > 0 {
@ -70,7 +70,7 @@ func parseQuota(quota QuotaRecord) []interface{} {
quota_map := make(map[string]interface{})
quota_map["cpu"] = quota.Cpu
quota_map["ram"] = quota.Ram
quota_map["ram"] = quota.Ram // MB; this is float32, unlike the rest of values
quota_map["disk"] = quota.Disk
quota_map["ext_traffic"] = quota.ExtTraffic
quota_map["ext_ips"] = quota.ExtIPs
@ -84,42 +84,42 @@ func parseQuota(quota QuotaRecord) []interface{} {
func quotaRgSubresourceSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"cpu": &schema.Schema{
"cpu": {
Type: schema.TypeInt,
Optional: true,
Default: -1,
Description: "Limit on the total number of CPUs in this resource group.",
},
"ram": &schema.Schema{
Type: schema.TypeInt, // NB: old API expects and returns this as float! This may be changed in the future.
"ram": {
Type: schema.TypeFloat, // NB: API expects and returns this as float in units of MB! This may be changed in the future.
Optional: true,
Default: -1,
Default: -1.,
Description: "Limit on the total amount of RAM in this resource group, specified in MB.",
},
"disk": &schema.Schema{
"disk": {
Type: schema.TypeInt,
Optional: true,
Default: -1,
Description: "Limit on the total volume of storage resources in this resource group, specified in GB.",
},
"ext_traffic": &schema.Schema{
"ext_traffic": {
Type: schema.TypeInt,
Optional: true,
Default: -1,
Description: "Limit on the total ingress network traffic for this resource group, specified in GB.",
},
"ext_ips": &schema.Schema{
"ext_ips": {
Type: schema.TypeInt,
Optional: true,
Default: -1,
Description: "Limit on the total number of external IP addresses this resource group can use.",
},
"gpu_units": &schema.Schema{
"gpu_units": {
Type: schema.TypeInt,
Optional: true,
Default: -1,

@ -341,6 +341,7 @@ func resourceCompute() *schema.Resource {
Description: "Name of the account this compute instance belongs to.",
},
/*
"disks": {
Type: schema.TypeList,
Computed: true,
@ -358,6 +359,7 @@ func resourceCompute() *schema.Resource {
},
Description: "Specification for the virtual NICs configured on this compute instance.",
},
*/
"guest_logins": {
Type: schema.TypeList,

@ -174,7 +174,7 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk))
}
if quotarecord_new.Ram != quotarecord_old.Ram {
if quotarecord_new.Ram != quotarecord_old.Ram { // NB: quota on RAM is stored as float32, in units of MB
do_update = true
log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram)
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram))
@ -275,57 +275,57 @@ func resourceResgroup() *schema.Resource {
},
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of this resource group. Names are case sensitive and unique within the context of a account.",
},
"account_id": &schema.Schema{
"account_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the account, which this resource group belongs to. If account ID is specified, then account name is ignored.",
},
"account_name": &schema.Schema{
"account_name": {
Type: schema.TypeString,
Optional: true,
Description: "Name of the account, which this resource group belongs to.",
},
"def_net_type": &schema.Schema{
"def_net_type": {
Type: schema.TypeString,
Optional: true,
Default: "PRIVATE",
Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.",
},
"def_net_id": &schema.Schema{
"def_net_id": {
Type: schema.TypeInt,
Computed: true,
Description: "ID of the default network for this resource group (if any).",
},
"ipcidr": &schema.Schema{
"ipcidr": {
Type: schema.TypeString,
Optional: true,
Description: "Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE",
},
"ext_net_id": &schema.Schema{
"ext_net_id": {
Type: schema.TypeInt,
Optional: true,
Default: 0,
Description: "ID of the external network, which this resource group will use as default for its computes if def_net_type=PUBLIC",
},
"ext_ip": &schema.Schema{
"ext_ip": {
Type: schema.TypeString,
Optional: true,
Description: "IP address on the external netowrk to request, if def_net_type=PUBLIC",
},
"grid_id": &schema.Schema{ // change of Grid ID will require new RG
"grid_id": { // change of Grid ID will require new RG
Type: schema.TypeInt,
Required: true,
Description: "Unique ID of the grid, where this resource group is deployed.",

@ -167,7 +167,7 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
urlValues.Add("computeId", d.Id())
urlValues.Add("netType", net_data["net_type"].(string))
urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
ipaddr, ipSet := net_data["ipaddr"] // "ipaddr" key is optional
ipaddr, ipSet := net_data["ip_address"] // "ip_address" key is optional
if ipSet {
urlValues.Add("ipAddr", ipaddr.(string))
}

Loading…
Cancel
Save