End of day backup commit
This commit is contained in:
@@ -63,8 +63,8 @@ type ControllerCfg struct {
|
|||||||
app_id string // required for oauth2 mode
|
app_id string // required for oauth2 mode
|
||||||
app_secret string // required for oauth2 mode
|
app_secret string // required for oauth2 mode
|
||||||
oauth2_url string // always required
|
oauth2_url string // always required
|
||||||
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
|
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
|
||||||
cc_client *http.Client // assigned when all initial check successfully passed
|
cc_client *http.Client // assigned when all initial checks successfully passed
|
||||||
}
|
}
|
||||||
|
|
||||||
func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2019-2020 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -39,24 +39,23 @@ import (
|
|||||||
func flattenResgroup(d *schema.ResourceData, rg_facts string) error {
|
func flattenResgroup(d *schema.ResourceData, rg_facts string) error {
|
||||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||||
// from resourceRsgroupExists(...) method
|
// from resourceRsgroupExists(...) method
|
||||||
log.Printf("%s", rg_facts)
|
log.Debugf("%s", rg_facts)
|
||||||
log.Printf("flattenResgroup: ready to decode response body from %q", CloudspacesGetAPI)
|
log.Debugf("flattenResgroup: ready to decode response body from %q", CloudspacesGetAPI)
|
||||||
details := CloudspacesGetResp{}
|
details := ResgroupGetResp{}
|
||||||
err := json.Unmarshal([]byte(rg_facts), &details)
|
err := json.Unmarshal([]byte(rg_facts), &details)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("flattenResgroup: decoded ResGroup name %q / ID %d, tenant ID %d, public IP %q",
|
log.Debugf("flattenResgroup: decoded ResGroup name %q / ID %d, account ID %d, public IP %q",
|
||||||
details.Name, details.ID, details.TenantID, details.PublicIP)
|
details.Name, details.ID, details.AccountID, details.PublicIP)
|
||||||
|
|
||||||
d.SetId(fmt.Sprintf("%d", details.ID))
|
d.SetId(fmt.Sprintf("%d", details.ID))
|
||||||
d.Set("name", details.Name)
|
d.Set("name", details.Name)
|
||||||
d.Set("tenant_id", details.TenantID)
|
d.Set("account_id", details.AccountID)
|
||||||
d.Set("grid_id", details.GridID)
|
d.Set("grid_id", details.GridID)
|
||||||
d.Set("public_ip", details.PublicIP) // legacy field - this may be obsoleted when new network segments are implemented
|
|
||||||
|
|
||||||
log.Printf("flattenResgroup: calling flattenQuota()")
|
log.Debugf("flattenResgroup: calling flattenQuota()")
|
||||||
if err = d.Set("quotas", flattenQuota(details.Quotas)); err != nil {
|
if err = d.Set("quotas", flattenQuota(details.Quotas)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -69,7 +68,7 @@ func dataSourceResgroupRead(d *schema.ResourceData, m interface{}) error {
|
|||||||
if rg_facts == "" {
|
if rg_facts == "" {
|
||||||
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
||||||
// such resource group and err tells so - just return it to the calling party
|
// such resource group and err tells so - just return it to the calling party
|
||||||
d.SetId("") // ensure ID is empty
|
d.SetId("") // ensure ID is empty in this case
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,13 +94,13 @@ func dataSourceResgroup() *schema.Resource {
|
|||||||
Description: "Name of this resource group. Names are case sensitive and unique within the context of a tenant.",
|
Description: "Name of this resource group. Names are case sensitive and unique within the context of a tenant.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"tenant": &schema.Schema {
|
"account": &schema.Schema {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "Name of the tenant, which this resource group belongs to.",
|
Description: "Name of the tenant, which this resource group belongs to.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"tenant_id": &schema.Schema {
|
"account_id": &schema.Schema {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "Unique ID of the tenant, which this resource group belongs to.",
|
Description: "Unique ID of the tenant, which this resource group belongs to.",
|
||||||
@@ -113,12 +112,6 @@ func dataSourceResgroup() *schema.Resource {
|
|||||||
Description: "Unique ID of the grid, where this resource group is deployed.",
|
Description: "Unique ID of the grid, where this resource group is deployed.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"location": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Location of this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"public_ip": { // this may be obsoleted as new network segments and true resource groups are implemented
|
"public_ip": { // this may be obsoleted as new network segments and true resource groups are implemented
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ type AccountAclRecord struct {
|
|||||||
type ResgroupRecord struct {
|
type ResgroupRecord struct {
|
||||||
ACLs []UserAclRecord `json:"ACLs"`
|
ACLs []UserAclRecord `json:"ACLs"`
|
||||||
Owner AccountAclRecord `json:"accountAcl"`
|
Owner AccountAclRecord `json:"accountAcl"`
|
||||||
TenantID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
TenantName string `json:"accountName"`
|
AccountName string `json:"accountName"`
|
||||||
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"`
|
||||||
@@ -85,23 +85,6 @@ type ResgroupListResp []ResgroupRecord
|
|||||||
// structures related to /cloudapi/rg/create API call
|
// structures related to /cloudapi/rg/create API call
|
||||||
//
|
//
|
||||||
const ResgroupCreateAPI= "/restmachine/cloudapi/rg/create"
|
const ResgroupCreateAPI= "/restmachine/cloudapi/rg/create"
|
||||||
type ResgroupCreateParam struct {
|
|
||||||
TenantID int `json:"accountId"`
|
|
||||||
GridId int `json:"gid"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Ram int `json:"maxMemoryCapacity"`
|
|
||||||
Disk int `json:"maxVDiskCapacity"`
|
|
||||||
Cpu int `json:"maxCPUCapacity"`
|
|
||||||
NetTraffic int `json:"maxNetworkPeerTransfer"`
|
|
||||||
ExtIPs int `json:"maxNumPublicIP"`
|
|
||||||
Owner string `json:"owner"`
|
|
||||||
DefNet string `json:"def_net"`
|
|
||||||
IPCidr string `json:"ipcidr"`
|
|
||||||
Desc string `json:"decs"`
|
|
||||||
Reason string `json:"reason"`
|
|
||||||
ExtNetID int `json:"extNetId"`
|
|
||||||
ExtIP string `json:"extIp"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// structures related to /cloudapi/rg/update API call
|
// structures related to /cloudapi/rg/update API call
|
||||||
@@ -139,8 +122,8 @@ 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"`
|
||||||
TenantID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
TenantName string `json:"accountName"`
|
AccountName string `json:"accountName"`
|
||||||
|
|
||||||
CreatedBy string `json:"createdBy"`
|
CreatedBy string `json:"createdBy"`
|
||||||
CreatedTime uint64 `json:"createdTime"`
|
CreatedTime uint64 `json:"createdTime"`
|
||||||
@@ -182,11 +165,6 @@ type ResgroupUpdateParam struct {
|
|||||||
// structures related to /cloudapi/rg/delete API
|
// structures related to /cloudapi/rg/delete API
|
||||||
//
|
//
|
||||||
const ResgroupDeleteAPI = "/restmachine/cloudapi/rg/delete"
|
const ResgroupDeleteAPI = "/restmachine/cloudapi/rg/delete"
|
||||||
type ResgroupDeleteParam struct {
|
|
||||||
ID uint `json:"rgId"`
|
|
||||||
Force bool `json:"force"`
|
|
||||||
Reason string `json:"reason"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// structures related to /cloudapi/kvmXXX/create APIs
|
// structures related to /cloudapi/kvmXXX/create APIs
|
||||||
@@ -245,8 +223,8 @@ type SnapSetRecord struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ComputeRecord struct {
|
type ComputeRecord struct {
|
||||||
TenantID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
TenantName string `json:"accountName"`
|
AccountName string `json:"accountName"`
|
||||||
ACLs []UserAclRecord `json:"acl"`
|
ACLs []UserAclRecord `json:"acl"`
|
||||||
Arch string `json:"arch"`
|
Arch string `json:"arch"`
|
||||||
BootDiskSize int `json:"bootdiskSize"`
|
BootDiskSize int `json:"bootdiskSize"`
|
||||||
@@ -302,7 +280,7 @@ type SnapshotRecord struct {
|
|||||||
type DiskRecord struct {
|
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"`
|
||||||
TenantID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
BootPartition int `json:"bootPartition"`
|
BootPartition int `json:"bootPartition"`
|
||||||
CreatedTime uint64 `json:"creationTime"`
|
CreatedTime uint64 `json:"creationTime"`
|
||||||
DeletedTime uint64 `json:"deletionTime"`
|
DeletedTime uint64 `json:"deletionTime"`
|
||||||
@@ -347,8 +325,8 @@ type ComputeGetParam struct {
|
|||||||
}
|
}
|
||||||
type ComputeGetResp struct {
|
type ComputeGetResp struct {
|
||||||
// ACLs `json:"ACL"` - it is a dictionary, special parsing required
|
// ACLs `json:"ACL"` - it is a dictionary, special parsing required
|
||||||
TenantID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
TenantName string `json:"accountName"`
|
AccountName string `json:"accountName"`
|
||||||
Arch string `json:"arch"`
|
Arch string `json:"arch"`
|
||||||
BootDiskSize int `json:"bootdiskSize"`
|
BootDiskSize int `json:"bootdiskSize"`
|
||||||
CloneReference int `json:"cloneReference"`
|
CloneReference int `json:"cloneReference"`
|
||||||
@@ -391,7 +369,7 @@ type ComputeGetResp struct {
|
|||||||
// structures related to /restmachine/cloudapi/images/list API
|
// structures related to /restmachine/cloudapi/images/list API
|
||||||
//
|
//
|
||||||
type ImageRecord struct {
|
type ImageRecord struct {
|
||||||
TenantID uint `json:"accountId"`
|
AccountID uint `json:"accountId"`
|
||||||
Arch string `json:"architecture`
|
Arch string `json:"architecture`
|
||||||
BootType string `json:"bootType"`
|
BootType string `json:"bootType"`
|
||||||
IsBootable boo `json:"bootable"`
|
IsBootable boo `json:"bootable"`
|
||||||
@@ -411,7 +389,7 @@ type ImageRecord struct {
|
|||||||
|
|
||||||
const ImagesListAPI = "/restmachine/cloudapi/images/list"
|
const ImagesListAPI = "/restmachine/cloudapi/images/list"
|
||||||
type ImagesListParam struct {
|
type ImagesListParam struct {
|
||||||
TenantID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
}
|
}
|
||||||
type ImagesListResp []ImageRecord
|
type ImagesListResp []ImageRecord
|
||||||
|
|
||||||
@@ -426,7 +404,7 @@ type ExtNetRecord struct {
|
|||||||
|
|
||||||
const ExtNetListAPI = "/restmachine/cloudapi/extnet/list"
|
const ExtNetListAPI = "/restmachine/cloudapi/extnet/list"
|
||||||
type ExtNetListParam struct {
|
type ExtNetListParam struct {
|
||||||
TenantID int `json:"accountId"`
|
AccountID int `json:"accountId"`
|
||||||
}
|
}
|
||||||
type ExtNetListResp []ExtNetRecord
|
type ExtNetListResp []ExtNetRecord
|
||||||
|
|
||||||
@@ -434,7 +412,7 @@ type ExtNetListResp []ExtNetRecord
|
|||||||
//
|
//
|
||||||
// structures related to /cloudapi/accounts/list API
|
// structures related to /cloudapi/accounts/list API
|
||||||
//
|
//
|
||||||
type TenantRecord struct {
|
type AccountRecord struct {
|
||||||
ACLs []UserAclRecord `json:"acl"`
|
ACLs []UserAclRecord `json:"acl"`
|
||||||
CreatedTime uint64 `json:"creationTime"`
|
CreatedTime uint64 `json:"creationTime"`
|
||||||
DeletedTime uint64 `json:"deletionTime"`
|
DeletedTime uint64 `json:"deletionTime"`
|
||||||
@@ -444,8 +422,8 @@ type TenantRecord struct {
|
|||||||
UpdatedTime uint64 `json:"updateTime"`
|
UpdatedTime uint64 `json:"updateTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const TenantsListAPI = "/restmachine/cloudapi/accounts/list"
|
const AccountsListAPI = "/restmachine/cloudapi/accounts/list"
|
||||||
type TenantsListResp []TenantRecord
|
type AccountsListResp []AccountRecord
|
||||||
|
|
||||||
//
|
//
|
||||||
// structures related to /cloudapi/portforwarding/list API
|
// structures related to /cloudapi/portforwarding/list API
|
||||||
@@ -516,7 +494,7 @@ const ComputeDiskDetachAPI = "/restmachine/cloudapi/compute/diskDetach"
|
|||||||
// structures related to /cloudapi/disks/create
|
// structures related to /cloudapi/disks/create
|
||||||
//
|
//
|
||||||
type DiskCreateParam struct {
|
type DiskCreateParam struct {
|
||||||
TenantID int `json:"accountId`
|
AccountID int `json:"accountId`
|
||||||
GridID int `json:"gid"`
|
GridID int `json:"gid"`
|
||||||
Name string `json:"string"`
|
Name string `json:"string"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2019-2020 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -24,6 +24,8 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
|
|||||||
|
|
||||||
package decort
|
package decort
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
type DiskConfig struct {
|
type DiskConfig struct {
|
||||||
Label string
|
Label string
|
||||||
Size int
|
Size int
|
||||||
@@ -65,7 +67,7 @@ type ComputeConfig struct {
|
|||||||
Description string
|
Description string
|
||||||
// The following two parameters are required to create data disks by
|
// The following two parameters are required to create data disks by
|
||||||
// a separate disks/create API call
|
// a separate disks/create API call
|
||||||
TenantID int
|
AccountID int
|
||||||
GridID int
|
GridID int
|
||||||
// The following one paratmeter is required to create port forwards
|
// The following one paratmeter is required to create port forwards
|
||||||
// it will be obsoleted when we implement true Resource Groups
|
// it will be obsoleted when we implement true Resource Groups
|
||||||
@@ -81,8 +83,8 @@ type ResgroupQuotaConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ResgroupConfig struct {
|
type ResgroupConfig struct {
|
||||||
TenantID int
|
AccountID int
|
||||||
TenantName string
|
AccountName string
|
||||||
Location string
|
Location string
|
||||||
Name string
|
Name string
|
||||||
ID int
|
ID int
|
||||||
@@ -90,4 +92,6 @@ type ResgroupConfig struct {
|
|||||||
ExtIP string // legacy field for VDC - this will eventually become obsoleted by true Resource Groups
|
ExtIP string // legacy field for VDC - this will eventually become obsoleted by true Resource Groups
|
||||||
Quota ResgroupQuotaConfig
|
Quota ResgroupQuotaConfig
|
||||||
Network NetworkConfig
|
Network NetworkConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2019 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package decs
|
package decort
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
||||||
@@ -100,14 +100,18 @@ func Provider() *schema.Provider {
|
|||||||
},
|
},
|
||||||
|
|
||||||
ResourcesMap: map[string]*schema.Resource {
|
ResourcesMap: map[string]*schema.Resource {
|
||||||
"decs_resgroup": resourceResgroup(),
|
"decort_resgroup": resourceResgroup(),
|
||||||
"decs_vm": resourceVm(),
|
"decort_kvmx86": resourceKvmX86(),
|
||||||
|
"decort_disk": resourceDisk(),
|
||||||
|
"decort_vins": resourceVins(),
|
||||||
},
|
},
|
||||||
|
|
||||||
DataSourcesMap: map[string]*schema.Resource {
|
DataSourcesMap: map[string]*schema.Resource {
|
||||||
"decs_resgroup": dataSourceResgroup(),
|
"decort_resgroup": dataSourceResgroup(),
|
||||||
"decs_vm": dataSourceVm(),
|
"decs_kvmx86": dataSourceCompute(),
|
||||||
"decs_image": dataSourceImage(),
|
"decort_image": dataSourceImage(),
|
||||||
|
"decort_disk": dataSourceDisk(),
|
||||||
|
"decort_vins": dataSourceVins(),
|
||||||
},
|
},
|
||||||
|
|
||||||
ConfigureFunc: providerConfigure,
|
ConfigureFunc: providerConfigure,
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
||||||
log.Printf("resourceResgroupCreate: called for res group name %q, tenant name %q",
|
log.Debugf("resourceResgroupCreate: called for res group name %q, account name %q",
|
||||||
d.Get("name").(string), d.Get("tenant").(string))
|
d.Get("name").(string), d.Get("account").(string))
|
||||||
|
|
||||||
rg := &ResgroupConfig{
|
rg := &ResgroupConfig{
|
||||||
Name: d.Get("name").(string),
|
Name: d.Get("name").(string),
|
||||||
TenantName: d.Get("tenant").(string),
|
AccountName: d.Get("account").(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate that we have all parameters required to create the new Resource Group
|
// validate that we have all parameters required to create the new Resource Group
|
||||||
@@ -49,35 +49,55 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
|||||||
if arg_set {
|
if arg_set {
|
||||||
rg.Location = arg_value.(string)
|
rg.Location = arg_value.(string)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("Cannot create new resource group %q for tenant %q: missing location parameter.",
|
return fmt.Errorf("Cannot create new RG %q for account %q: missing location parameter.",
|
||||||
rg.Name, rg.TenantName)
|
rg.Name, rg.AccountName)
|
||||||
}
|
}
|
||||||
// tenant ID is required to create new resource group
|
// account ID is required to create new resource group
|
||||||
// obtain Tenant ID by tenant name - it should not be zero on success
|
// obtain Account ID by account name - it should not be zero on success
|
||||||
tenant_id, err := utilityGetTenantIdByName(rg.TenantName, m)
|
account_id, err := utilityGetAccountIdByName(rg.AccountName, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rg.TenantID = tenant_id
|
rg.AccountID = account_id
|
||||||
|
|
||||||
set_quotas := false
|
set_quotas := false
|
||||||
arg_value, arg_set = d.GetOk("quotas")
|
arg_value, arg_set = d.GetOk("quotas")
|
||||||
if arg_set {
|
if arg_set {
|
||||||
log.Printf("resourceResgroupCreate: calling makeQuotaConfig")
|
log.Debugf("resourceResgroupCreate: calling makeQuotaConfig")
|
||||||
rg.Quota, _ = makeQuotaConfig(arg_value.([]interface{}))
|
rg.Quota, _ = makeQuotaConfig(arg_value.([]interface{}))
|
||||||
set_quotas = true
|
set_quotas = true
|
||||||
}
|
}
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
controller := m.(*ControllerCfg)
|
||||||
log.Printf("resourceResgroupCreate: called by user %q for Resource group name %q, for tenant %q / ID %d, location %q",
|
log.Debugf("resourceResgroupCreate: called by user %q for RG name %q, for account %q / ID %d, location %q",
|
||||||
controller.getdecortUsername(),
|
controller.getdecortUsername(),
|
||||||
rg.Name, d.Get("tenant"), rg.TenantID, rg.Location)
|
rg.Name, d.Get("account").(string), rg.AccountID, rg.Location)
|
||||||
|
/*
|
||||||
|
type ResgroupCreateParam struct {
|
||||||
|
AccountID int `json:"accountId"`
|
||||||
|
GridId int `json:"gid"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Ram int `json:"maxMemoryCapacity"`
|
||||||
|
Disk int `json:"maxVDiskCapacity"`
|
||||||
|
Cpu int `json:"maxCPUCapacity"`
|
||||||
|
NetTraffic int `json:"maxNetworkPeerTransfer"`
|
||||||
|
ExtIPs int `json:"maxNumPublicIP"`
|
||||||
|
Owner string `json:"owner"`
|
||||||
|
DefNet string `json:"def_net"`
|
||||||
|
IPCidr string `json:"ipcidr"`
|
||||||
|
Desc string `json:"decs"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
ExtNetID int `json:"extNetId"`
|
||||||
|
ExtIP string `json:"extIp"`
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
url_values := &url.Values{}
|
url_values := &url.Values{}
|
||||||
url_values.Add("accountId", fmt.Sprintf("%d", rg.TenantID))
|
url_values.Add("accountId", fmt.Sprintf("%d", rg.AccountID))
|
||||||
url_values.Add("name", rg.Name)
|
url_values.Add("name", rg.Name)
|
||||||
url_values.Add("location", rg.Location)
|
url_values.Add("gid", rg.Location)
|
||||||
url_values.Add("access", controller.getdecortUsername())
|
url_values.Add("owner", controller.getdecortUsername())
|
||||||
|
url_values.Add("def_net", "NONE")
|
||||||
// pass quota values as set
|
// pass quota values as set
|
||||||
if set_quotas {
|
if set_quotas {
|
||||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", rg.Quota.Cpu))
|
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", rg.Quota.Cpu))
|
||||||
@@ -89,7 +109,7 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
|||||||
// pass externalnetworkid if set
|
// pass externalnetworkid if set
|
||||||
arg_value, arg_set = d.GetOk("extnet_id")
|
arg_value, arg_set = d.GetOk("extnet_id")
|
||||||
if arg_set {
|
if arg_set {
|
||||||
url_values.Add("externalnetworkid", fmt.Sprintf("%d", arg_value))
|
url_values.Add("extNetId", fmt.Sprintf("%d", arg_value))
|
||||||
}
|
}
|
||||||
|
|
||||||
api_resp, err := controller.decortAPICall("POST", ResgroupCreateAPI, url_values)
|
api_resp, err := controller.decortAPICall("POST", ResgroupCreateAPI, url_values)
|
||||||
@@ -97,15 +117,15 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(api_resp) // cloudspaces/create API plainly returns ID of the newly creted resource group on success
|
d.SetId(api_resp) // rg/create API returns ID of the newly creted resource group on success
|
||||||
rg.ID, _ = strconv.Atoi(api_resp)
|
rg.ID, _ = strconv.Atoi(api_resp)
|
||||||
|
|
||||||
return resourceResgroupRead(d, m)
|
return resourceResgroupRead(d, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceResgroupRead(d *schema.ResourceData, m interface{}) error {
|
func resourceResgroupRead(d *schema.ResourceData, m interface{}) error {
|
||||||
log.Printf("resourceResgroupRead: called for res group name %q, tenant name %q",
|
log.Debugf("resourceResgroupRead: called for RG name %q, account name %q",
|
||||||
d.Get("name").(string), d.Get("tenant").(string))
|
d.Get("name").(string), d.Get("account").(string))
|
||||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
||||||
if rg_facts == "" {
|
if rg_facts == "" {
|
||||||
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
||||||
@@ -119,13 +139,13 @@ func resourceResgroupRead(d *schema.ResourceData, m interface{}) error {
|
|||||||
|
|
||||||
func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
||||||
// this method will only update quotas, if any are set
|
// this method will only update quotas, if any are set
|
||||||
log.Printf("resourceResgroupUpdate: called for res group name %q, tenant name %q",
|
log.Debugf("resourceResgroupUpdate: called for RG name %q, account name %q",
|
||||||
d.Get("name").(string), d.Get("tenant").(string))
|
d.Get("name").(string), d.Get("account").(string))
|
||||||
|
|
||||||
quota_value, arg_set := d.GetOk("quotas")
|
quota_value, arg_set := d.GetOk("quotas")
|
||||||
if !arg_set {
|
if !arg_set {
|
||||||
// if there are no quotas set explicitly in the resource configuration - no change will be done
|
// if there are no quotas set explicitly in the resource configuration - no change will be done
|
||||||
log.Printf("resourceResgroupUpdate: quotas are not set in the resource config - no update on this resource will be done")
|
log.Debugf("resourceResgroupUpdate: quotas are not set in the resource config - no update on this resource will be done")
|
||||||
return resourceResgroupRead(d, m)
|
return resourceResgroupRead(d, m)
|
||||||
}
|
}
|
||||||
quotaconfig_new, _ := makeQuotaConfig(quota_value.([]interface{}))
|
quotaconfig_new, _ := makeQuotaConfig(quota_value.([]interface{}))
|
||||||
@@ -142,66 +162,68 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
|||||||
|
|
||||||
if quotaconfig_new.Cpu != quotaconfig_old.Cpu {
|
if quotaconfig_new.Cpu != quotaconfig_old.Cpu {
|
||||||
do_update = true
|
do_update = true
|
||||||
log.Printf("resourceResgroupUpdate: Cpu diff %d <- %d", quotaconfig_new.Cpu, quotaconfig_old.Cpu)
|
log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotaconfig_new.Cpu, quotaconfig_old.Cpu)
|
||||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotaconfig_new.Cpu))
|
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotaconfig_new.Cpu))
|
||||||
}
|
}
|
||||||
|
|
||||||
if quotaconfig_new.Disk != quotaconfig_old.Disk {
|
if quotaconfig_new.Disk != quotaconfig_old.Disk {
|
||||||
do_update = true
|
do_update = true
|
||||||
log.Printf("resourceResgroupUpdate: Disk diff %d <- %d", quotaconfig_new.Disk, quotaconfig_old.Disk)
|
log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotaconfig_new.Disk, quotaconfig_old.Disk)
|
||||||
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotaconfig_new.Disk))
|
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotaconfig_new.Disk))
|
||||||
}
|
}
|
||||||
|
|
||||||
if quotaconfig_new.Ram != quotaconfig_old.Ram {
|
if quotaconfig_new.Ram != quotaconfig_old.Ram {
|
||||||
do_update = true
|
do_update = true
|
||||||
log.Printf("resourceResgroupUpdate: Ram diff %f <- %f", quotaconfig_new.Ram, quotaconfig_old.Ram)
|
log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotaconfig_new.Ram, quotaconfig_old.Ram)
|
||||||
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotaconfig_new.Ram))
|
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotaconfig_new.Ram))
|
||||||
}
|
}
|
||||||
|
|
||||||
if quotaconfig_new.NetTraffic != quotaconfig_old.NetTraffic {
|
if quotaconfig_new.NetTraffic != quotaconfig_old.NetTraffic {
|
||||||
do_update = true
|
do_update = true
|
||||||
log.Printf("resourceResgroupUpdate: NetTraffic diff %d <- %d", quotaconfig_new.NetTraffic, quotaconfig_old.NetTraffic)
|
log.Debugf("resourceResgroupUpdate: NetTraffic diff %d <- %d", quotaconfig_new.NetTraffic, quotaconfig_old.NetTraffic)
|
||||||
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotaconfig_new.NetTraffic))
|
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotaconfig_new.NetTraffic))
|
||||||
}
|
}
|
||||||
|
|
||||||
if quotaconfig_new.ExtIPs != quotaconfig_old.ExtIPs {
|
if quotaconfig_new.ExtIPs != quotaconfig_old.ExtIPs {
|
||||||
do_update = true
|
do_update = true
|
||||||
log.Printf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotaconfig_new.ExtIPs, quotaconfig_old.ExtIPs)
|
log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotaconfig_new.ExtIPs, quotaconfig_old.ExtIPs)
|
||||||
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotaconfig_new.ExtIPs))
|
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotaconfig_new.ExtIPs))
|
||||||
}
|
}
|
||||||
|
|
||||||
if do_update {
|
if do_update {
|
||||||
log.Printf("resourceResgroupUpdate: some new quotas are set - updating the resource")
|
log.Debugf("resourceResgroupUpdate: some new quotas are set - updating the resource")
|
||||||
_, err := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values)
|
_, err := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("resourceResgroupUpdate: no difference in quotas between old and new state - no update on this resource will be done")
|
log.Debugf("resourceResgroupUpdate: no difference in quotas between old and new state - no update on this resource will be done")
|
||||||
}
|
}
|
||||||
|
|
||||||
return resourceResgroupRead(d, m)
|
return resourceResgroupRead(d, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error {
|
func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error {
|
||||||
// NOTE: this method destroys target resource group with flag "permanently", so there is no way to
|
// NOTE: this method forcibly destroys target resource group with flag "permanently", so there is no way to
|
||||||
// restore the destroyed resource group as well all VMs that existed in it
|
// restore the destroyed resource group as well all Computes & VINSes that existed in it
|
||||||
log.Printf("resourceResgroupDelete: called for res group name %q, tenant name %q",
|
log.Debugf("resourceResgroupDelete: called for RG name %q, account name %q",
|
||||||
d.Get("name").(string), d.Get("tenant").(string))
|
d.Get("name").(string), d.Get("account").(string))
|
||||||
|
|
||||||
vm_facts, err := utilityResgroupCheckPresence(d, m)
|
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
||||||
if vm_facts == "" {
|
if rg_facts == "" {
|
||||||
// the target VM does not exist - in this case according to Terraform best practice
|
// the target RG does not exist - in this case according to Terraform best practice
|
||||||
// we exit from Destroy method without error
|
// we exit from Destroy method without error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
params := &url.Values{}
|
params := &url.Values{}
|
||||||
params.Add("cloudspaceId", d.Id())
|
params.Add("rgId", d.Id())
|
||||||
|
params.Add("force", "true")
|
||||||
params.Add("permanently", "true")
|
params.Add("permanently", "true")
|
||||||
|
params.Add("reason", "Destroyed by DECORT Terraform provider")
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
controller := m.(*ControllerCfg)
|
||||||
vm_facts, err = controller.decortAPICall("POST", CloudspacesDeleteAPI, params)
|
vm_facts, err = controller.decortAPICall("POST", ResgroupDeleteAPI, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -243,13 +265,13 @@ func resourceResgroup() *schema.Resource {
|
|||||||
"name": &schema.Schema {
|
"name": &schema.Schema {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "Name of this resource group. Names are case sensitive and unique within the context of a tenant.",
|
Description: "Name of this resource group. Names are case sensitive and unique within the context of a account.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"tenant": &schema.Schema {
|
"account": &schema.Schema {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "Name of the tenant, which this resource group belongs to.",
|
Description: "Name of the account, which this resource group belongs to.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"extnet_id": &schema.Schema {
|
"extnet_id": &schema.Schema {
|
||||||
@@ -258,31 +280,18 @@ func resourceResgroup() *schema.Resource {
|
|||||||
Description: "ID of the external network, which this resource group will be connected to by default.",
|
Description: "ID of the external network, which this resource group will be connected to by default.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"tenant_id": &schema.Schema {
|
"account_id": &schema.Schema {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "Unique ID of the tenant, which this resource group belongs to.",
|
Description: "Unique ID of the account, which this resource group belongs to.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"grid_id": &schema.Schema {
|
"grid_id": &schema.Schema {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Computed: true,
|
Required: true,
|
||||||
Description: "Unique ID of the grid, where this resource group is deployed.",
|
Description: "Unique ID of the grid, where this resource group is deployed.",
|
||||||
},
|
},
|
||||||
|
|
||||||
"location": &schema.Schema {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true, // note that it is a REQUIRED parameter when creating new resource group
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "Name of the location where this resource group should exist.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"public_ip": { // this may be obsoleted as new network segments and true resource groups are implemented
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Public IP address of this resource group (if any).",
|
|
||||||
},
|
|
||||||
|
|
||||||
"quotas": {
|
"quotas": {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2019-2020 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -36,23 +36,24 @@ import (
|
|||||||
// "github.com/hashicorp/terraform/helper/validation"
|
// "github.com/hashicorp/terraform/helper/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ctrl *ControllerCfg) utilityResgroupConfigGet(rgid int) (*ResgroupConfig, error) {
|
func (ctrl *ControllerCfg) utilityResgroupConfigGet(rgid int) (*ResgroupGetResp, error) {
|
||||||
url_values := &url.Values{}
|
url_values := &url.Values{}
|
||||||
url_values.Add("cloudspaceId", fmt.Sprintf("%d", rgid))
|
url_values.Add("rgId", fmt.Sprintf("%d", rgid))
|
||||||
resgroup_facts, err := ctrl.decortAPICall("POST", CloudspacesGetAPI, url_values)
|
resgroup_facts, err := ctrl.decortAPICall("POST", ResgroupGetAPI, url_values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("utilityResgroupConfigGet: ready to unmarshal string %q", resgroup_facts)
|
log.Debugf("utilityResgroupConfigGet: ready to unmarshal string %q", resgroup_facts)
|
||||||
model := CloudspacesGetResp{}
|
model := &ResgroupGetResp{}
|
||||||
err = json.Unmarshal([]byte(resgroup_facts), &model)
|
err = json.Unmarshal([]byte(resgroup_facts), model)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
ret := &ResgroupConfig{}
|
ret := &ResgroupConfig{}
|
||||||
ret.TenantID = model.TenantID
|
ret.AccountID = model.AccountID
|
||||||
ret.Location = model.Location
|
ret.Location = model.Location
|
||||||
ret.Name = model.Name
|
ret.Name = model.Name
|
||||||
ret.ID = rgid
|
ret.ID = rgid
|
||||||
@@ -60,53 +61,58 @@ func (ctrl *ControllerCfg) utilityResgroupConfigGet(rgid int) (*ResgroupConfig,
|
|||||||
ret.ExtIP = model.ExtIP // legacy field for VDC - this will eventually become obsoleted by true Resource Groups
|
ret.ExtIP = model.ExtIP // legacy field for VDC - this will eventually become obsoleted by true Resource Groups
|
||||||
// Quota ResgroupQuotaConfig
|
// Quota ResgroupQuotaConfig
|
||||||
// Network NetworkConfig
|
// Network NetworkConfig
|
||||||
log.Printf("utilityResgroupConfigGet: tenant ID %d, GridID %d, ExtIP %q",
|
*/
|
||||||
model.TenantID, model.GridID, model.ExtIP)
|
log.Debugf("utilityResgroupConfigGet: account ID %d, GridID %d, Name %s",
|
||||||
|
model.AccountID, model.GridID, model.Name)
|
||||||
|
|
||||||
return ret, nil
|
return model, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
||||||
// This function tries to locate resource group by its name and tenant name.
|
// This function tries to locate resource group by its name and account name.
|
||||||
// If succeeded, it returns non empty string that contains JSON formatted facts about the
|
// If succeeded, it returns non empty string that contains JSON formatted facts about the
|
||||||
// resource group as returned by cloudspaces/get API call.
|
// resource group as returned by cloudspaces/get API call.
|
||||||
// Otherwise it returns empty string and meaningful error.
|
// Otherwise it returns empty string and meaningful error.
|
||||||
//
|
//
|
||||||
|
// NOTE: As our provider always deletes RGs permanently, there is no "restore" method and
|
||||||
|
// consequently we are not interested in matching RGs in DELETED state. Hence, we call
|
||||||
|
// .../rg/list API with includedeleted=false
|
||||||
|
//
|
||||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||||
// method for the resource's Exists method.
|
// method for the resource's Exists method.
|
||||||
//
|
//
|
||||||
name := d.Get("name").(string)
|
name := d.Get("name").(string)
|
||||||
tenant_name := d.Get("tenant").(string)
|
account_name := d.Get("account").(string)
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
controller := m.(*ControllerCfg)
|
||||||
url_values := &url.Values{}
|
url_values := &url.Values{}
|
||||||
url_values.Add("includedeleted", "false")
|
url_values.Add("includedeleted", "false")
|
||||||
body_string, err := controller.decortAPICall("POST", CloudspacesListAPI, url_values)
|
body_string, err := controller.decortAPICall("POST", ResgroupListAPI, url_values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("%s", body_string)
|
log.Debugf("%s", body_string)
|
||||||
log.Printf("utilityResgroupCheckPresence: ready to decode response body from %q", CloudspacesListAPI)
|
log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %q", ResgroupListAPI)
|
||||||
model := CloudspacesListResp{}
|
model := CloudspacesListResp{}
|
||||||
err = json.Unmarshal([]byte(body_string), &model)
|
err = json.Unmarshal([]byte(body_string), &model)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model))
|
log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model))
|
||||||
for index, item := range model {
|
for index, item := range model {
|
||||||
// need to match VDC by name & tenant name
|
// need to match RG by name & account name
|
||||||
if item.Name == name && item.TenantName == tenant_name {
|
if item.Name == name && item.AccountName == account_name {
|
||||||
log.Printf("utilityResgroupCheckPresence: match ResGroup name %q / ID %d, tenant %q at index %d",
|
log.Debugf("utilityResgroupCheckPresence: match RG name %q / ID %d, account %q at index %d",
|
||||||
item.Name, item.ID, item.TenantName, index)
|
item.Name, item.ID, item.AccountName, index)
|
||||||
|
|
||||||
// not all required information is returned by cloudspaces/list API, so we need to initiate one more
|
// not all required information is returned by rg/list API, so we need to initiate one more
|
||||||
// call to cloudspaces/get to obtain extra data to complete Resource population.
|
// call to rg/get to obtain extra data to complete Resource population.
|
||||||
// Namely, we need to extract resource quota settings
|
// Namely, we need to extract resource quota settings
|
||||||
req_values := &url.Values{}
|
req_values := &url.Values{}
|
||||||
req_values.Add("cloudspaceId", fmt.Sprintf("%d", item.ID))
|
req_values.Add("rgId", fmt.Sprintf("%d", item.ID))
|
||||||
body_string, err := controller.decortAPICall("POST", CloudspacesGetAPI, req_values)
|
body_string, err := controller.decortAPICall("POST", ResgroupGetAPI, req_values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -115,32 +121,32 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("Cannot find resource group name %q owned by tenant %q", name, tenant_name)
|
return "", fmt.Errorf("Cannot find RG name %q owned by account %q", name, account_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func utilityGetTenantIdByName(tenant_name string, m interface{}) (int, error) {
|
func utilityGetAccountIdByName(account_name string, m interface{}) (int, error) {
|
||||||
controller := m.(*ControllerCfg)
|
controller := m.(*ControllerCfg)
|
||||||
url_values := &url.Values{}
|
url_values := &url.Values{}
|
||||||
body_string, err := controller.decortAPICall("POST", TenantsListAPI, url_values)
|
body_string, err := controller.decortAPICall("POST", AccountsListAPI, url_values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
model := TenantsListResp{}
|
model := AccountsListResp{}
|
||||||
err = json.Unmarshal([]byte(body_string), &model)
|
err = json.Unmarshal([]byte(body_string), &model)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("utilityGetTenantIdByName: traversing decoded Json of length %d", len(model))
|
log.Debugf("utilityGetAccountIdByName: traversing decoded Json of length %d", len(model))
|
||||||
for index, item := range model {
|
for index, item := range model {
|
||||||
// need to match Tenant by name
|
// need to match Account by name
|
||||||
if item.Name == tenant_name {
|
if item.Name == account_name {
|
||||||
log.Printf("utilityGetTenantIdByName: match Tenant name %q / ID %d at index %d",
|
log.Debugf("utilityGetAccountIdByName: match Account name %q / ID %d at index %d",
|
||||||
item.Name, item.ID, index)
|
item.Name, item.ID, index)
|
||||||
return item.ID, nil
|
return item.ID, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, fmt.Errorf("Cannot find tenant %q for the current user. Check tenant value and your access rights", tenant_name)
|
return 0, fmt.Errorf("Cannot find account %q for the current user. Check account value and your access rights", account_name)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user