Add data function for an account

gos_tech_4.4.3
stSolo 3 years ago
parent 9912b04c2a
commit a0fbc8dd4f

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -25,45 +25,298 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
package decort package decort
import ( import (
"encoding/json" "github.com/google/uuid"
"fmt"
// "net/url"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
) )
func flattenAccount(d *schema.ResourceData, acc_facts string) error { func dataSourceAccountRead(d *schema.ResourceData, m interface{}) error {
// NOTE: this function modifies ResourceData argument - as such it should never be called acc, err := utilityAccountCheckPresence(d, m)
// from resourceAccountExists(...) method
// log.Debugf("flattenAccount: ready to decode response body from %q", CloudspacesGetAPI)
details := AccountRecord{}
err := json.Unmarshal([]byte(acc_facts), &details)
if err != nil { if err != nil {
return err return err
} }
log.Debugf("flattenAccount: decoded Account name %q / ID %d, status %q", details.Name, details.ID, details.Status) id := uuid.New()
d.SetId(id.String())
d.SetId(fmt.Sprintf("%d", details.ID)) d.Set("dc_location", acc.DCLocation)
d.Set("name", details.Name) d.Set("resources", flattenAccResources(acc.Resources))
d.Set("status", details.Status) d.Set("ckey", acc.CKey)
d.Set("meta", flattenMeta(acc.Meta))
d.Set("acl", flattenRgAcl(acc.Acl))
d.Set("company", acc.Company)
d.Set("companyurl", acc.CompanyUrl)
d.Set("created_by", acc.CreatedBy)
d.Set("created_time", acc.CreatedTime)
d.Set("deactivation_time", acc.DeactiovationTime)
d.Set("deleted_by", acc.DeletedBy)
d.Set("deleted_time", acc.DeletedTime)
d.Set("displayname", acc.DisplayName)
d.Set("guid", acc.GUID)
d.Set("account_id", acc.ID)
d.Set("account_name", acc.Name)
d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits))
d.Set("send_access_emails", acc.SendAccessEmails)
d.Set("service_account", acc.ServiceAccount)
d.Set("status", acc.Status)
d.Set("updated_time", acc.UpdatedTime)
d.Set("version", acc.Version)
d.Set("vins", acc.Vins)
return nil return nil
} }
func dataSourceAccountRead(d *schema.ResourceData, m interface{}) error { func flattenAccResources(r Resources) []map[string]interface{} {
acc_facts, err := utilityAccountCheckPresence(d, m) res := make([]map[string]interface{}, 0)
if acc_facts == "" { temp := map[string]interface{}{
// if empty string is returned from utilityAccountCheckPresence then there is no "current": flattenAccResource(r.Current),
// such account and err tells so - just return it to the calling party "reserved": flattenAccResource(r.Reserved),
d.SetId("") // ensure ID is empty in this case
return err
} }
res = append(res, temp)
return res
}
func flattenAccResource(r Resource) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"cpu": r.CPU,
"disksize": r.Disksize,
"extips": r.Extips,
"exttraffic": r.Exttraffic,
"gpu": r.GPU,
"ram": r.RAM,
}
res = append(res, temp)
return res
}
return flattenAccount(d, acc_facts) func dataSourceAccountSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"account_id": {
Type: schema.TypeInt,
Required: true,
},
"dc_location": {
Type: schema.TypeString,
Computed: true,
},
"resources": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"current": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cpu": {
Type: schema.TypeInt,
Computed: true,
},
"disksize": {
Type: schema.TypeInt,
Computed: true,
},
"extips": {
Type: schema.TypeInt,
Computed: true,
},
"exttraffic": {
Type: schema.TypeInt,
Computed: true,
},
"gpu": {
Type: schema.TypeInt,
Computed: true,
},
"ram": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"reserved": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cpu": {
Type: schema.TypeInt,
Computed: true,
},
"disksize": {
Type: schema.TypeInt,
Computed: true,
},
"extips": {
Type: schema.TypeInt,
Computed: true,
},
"exttraffic": {
Type: schema.TypeInt,
Computed: true,
},
"gpu": {
Type: schema.TypeInt,
Computed: true,
},
"ram": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
},
},
},
"ckey": {
Type: schema.TypeString,
Computed: true,
},
"meta": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"acl": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"explicit": {
Type: schema.TypeBool,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"right": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"user_group_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"company": {
Type: schema.TypeString,
Computed: true,
},
"companyurl": {
Type: schema.TypeString,
Computed: true,
},
"created_by": {
Type: schema.TypeString,
Computed: true,
},
"created_time": {
Type: schema.TypeInt,
Computed: true,
},
"deactivation_time": {
Type: schema.TypeFloat,
Computed: true,
},
"deleted_by": {
Type: schema.TypeString,
Computed: true,
},
"deleted_time": {
Type: schema.TypeInt,
Computed: true,
},
"displayname": {
Type: schema.TypeString,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"account_name": {
Type: schema.TypeString,
Computed: true,
},
"resource_limits": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cu_c": {
Type: schema.TypeFloat,
Computed: true,
},
"cu_d": {
Type: schema.TypeFloat,
Computed: true,
},
"cu_i": {
Type: schema.TypeFloat,
Computed: true,
},
"cu_m": {
Type: schema.TypeFloat,
Computed: true,
},
"cu_np": {
Type: schema.TypeFloat,
Computed: true,
},
"gpu_units": {
Type: schema.TypeFloat,
Computed: true,
},
},
},
},
"send_access_emails": {
Type: schema.TypeBool,
Computed: true,
},
"service_account": {
Type: schema.TypeBool,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"updated_time": {
Type: schema.TypeInt,
Computed: true,
},
"version": {
Type: schema.TypeInt,
Computed: true,
},
"vins": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
}
return res
} }
func dataSourceAccount() *schema.Resource { func dataSourceAccount() *schema.Resource {
@ -77,56 +330,6 @@ func dataSourceAccount() *schema.Resource {
Default: &Timeout60s, Default: &Timeout60s,
}, },
Schema: map[string]*schema.Schema{ Schema: dataSourceAccountSchemaMake(),
"name": {
Type: schema.TypeString,
Optional: true,
Description: "Name of the account. Names are case sensitive and unique.",
},
"account_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the account. If account ID is specified, then account name is ignored.",
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: "Current status of the account.",
},
/* We keep the following attributes commented out, as we are not implementing account
management with Terraform plugin, so we do not need this extra info.
"quota": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: quotaRgSubresourceSchema(), // this is a dictionary
},
Description: "Quotas on the resources for this account and all its resource groups.",
},
"resource_groups": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema {
Type: schema.TypeInt,
},
Description: "IDs of resource groups in this account."
},
"vins": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema {
Type: schema.TypeInt,
},
Description: "IDs of VINSes created at the account level."
},
*/
},
} }
} }

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

@ -1002,7 +1002,9 @@ const accountDeleteAccountsAPI = "/cloudapi/account/deleteAccounts"
const accountDeleteUserAPI = "/cloudapi/account/deleteUser" const accountDeleteUserAPI = "/cloudapi/account/deleteUser"
const accountDisableAPI = "/cloudapi/account/disable" const accountDisableAPI = "/cloudapi/account/disable"
const accountEnableAPI = "/cloudapi/account/enable" const accountEnableAPI = "/cloudapi/account/enable"
const accountGetAPI = "/cloudapi/account/get"
//const accountGetAPI = "/restmachine/cloudapi/account/get"
const accountGetAPI = "/restmachine/cloudbroker/account/get"
const accountGetConsumedAccountUnitsAPI = "/cloudapi/account/getConsumedAccountUnits" const accountGetConsumedAccountUnitsAPI = "/cloudapi/account/getConsumedAccountUnits"
const accountGetConsumedCloudUnitsByTypeAPI = "/cloudapi/account/getConsumedCloudUnitsByType" const accountGetConsumedCloudUnitsByTypeAPI = "/cloudapi/account/getConsumedCloudUnitsByType"
const accountGetConsumptionGetAPI = "/cloudapi/account/getConsumption" const accountGetConsumptionGetAPI = "/cloudapi/account/getConsumption"

@ -39,10 +39,6 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
// Valid account ID is required to create new resource group // Valid account ID is required to create new resource group
// obtain Account ID by account name - it should not be zero on success // obtain Account ID by account name - it should not be zero on success
validated_account_id, err := utilityGetAccountIdBySchema(d, m)
if err != nil {
return err
}
rg_name, arg_set := d.GetOk("name") rg_name, arg_set := d.GetOk("name")
if !arg_set { if !arg_set {
@ -62,7 +58,7 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
// all required parameters are set in the schema - we can continue with RG creation // all required parameters are set in the schema - we can continue with RG creation
log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d", log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d",
rg_name.(string), validated_account_id) rg_name.(string), d.Get("account_id").(int))
// quota settings are optional // quota settings are optional
set_quota := false set_quota := false
@ -77,10 +73,10 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
log.Debugf("resourceResgroupCreate: called by user %q for RG name %s, account ID %d", log.Debugf("resourceResgroupCreate: called by user %q for RG name %s, account ID %d",
controller.getDecortUsername(), controller.getDecortUsername(),
rg_name.(string), validated_account_id) rg_name.(string), d.Get("account_id").(int))
url_values := &url.Values{} url_values := &url.Values{}
url_values.Add("accountId", fmt.Sprintf("%d", validated_account_id)) url_values.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
url_values.Add("name", rg_name.(string)) url_values.Add("name", rg_name.(string))
url_values.Add("gid", fmt.Sprintf("%d", DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention url_values.Add("gid", fmt.Sprintf("%d", DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention
url_values.Add("owner", controller.getDecortUsername()) url_values.Add("owner", controller.getDecortUsername())

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com> Author: Stanislav Solovev, <spsolovev@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");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -26,131 +26,31 @@ package decort
import ( import (
"encoding/json" "encoding/json"
"fmt"
"net/url" "net/url"
"strconv"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
) )
func utilityAccountCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { func utilityAccountCheckPresence(d *schema.ResourceData, m interface{}) (*AccountWithResources, error) {
account := &AccountWithResources{}
controller := m.(*ControllerCfg) controller := m.(*ControllerCfg)
urlValues := &url.Values{} urlValues := &url.Values{}
accId, argSet := d.GetOk("account_id") urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
if argSet {
// get Account right away by its ID
log.Debugf("utilityAccountCheckPresence: locating Account by its ID %d", accId.(int))
urlValues.Add("accountId", fmt.Sprintf("%d", accId.(int)))
apiResp, err := controller.decortAPICall("POST", AccountsGetAPI, urlValues)
if err != nil {
return "", err
}
return apiResp, nil
}
accName, argSet := d.GetOk("name")
if !argSet {
// neither ID nor name - no account for you!
return "", fmt.Errorf("Cannot check account presence if name is empty and no account ID specified")
}
apiResp, err := controller.decortAPICall("POST", AccountsListAPI, urlValues)
if err != nil {
return "", err
}
// log.Debugf("%s", apiResp)
// log.Debugf("utilityAccountCheckPresence: ready to decode response body from %q", AccountsListAPI)
accList := AccountsListResp{}
err = json.Unmarshal([]byte(apiResp), &accList)
if err != nil {
return "", err
}
log.Debugf("utilityAccountCheckPresence: traversing decoded Json of length %d", len(accList))
for index, item := range accList {
// match by account name
if item.Name == accName.(string) {
log.Debugf("utilityAccountCheckPresence: match account name %q / ID %d at index %d",
item.Name, item.ID, index)
// NB: unlike accounts/get API, accounts/list API returns abridged set of account info,
// for instance it does not return quotas
reencodedItem, err := json.Marshal(item)
if err != nil {
return "", err
}
return string(reencodedItem[:]), nil
}
}
return "", fmt.Errorf("Cannot find account name %q", accName.(string))
}
func utilityGetAccountIdBySchema(d *schema.ResourceData, m interface{}) (int, error) { log.Debugf("utilityAccountCheckPresence: load account")
/* accountRaw, err := controller.decortAPICall("POST", accountGetAPI, urlValues)
This function expects schema that contains the following two elements:
"account_name": &schema.Schema{
Type: schema.TypeString,
Required: Optional,
Description: "Name of the account, ....",
},
"account_id": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Description: "Unique ID of the account, ....",
},
Then it will check, which argument is set, and if account name is present, it will
initiate API calls to the DECORT cloud controller and try to match relevant account
by the name.
NOTE that for some resources (most notably, Resource Group) "account_name" attribute is
marked as "Computed: true", so the only way to fully identify Resource Group is to specify
"account_id", which is marked as "Required: true"
*/
accId, argSet := d.GetOk("account_id")
if argSet {
if accId.(int) > 0 {
return accId.(int), nil
}
return 0, fmt.Errorf("Account ID must be positive")
}
accName, argSet := d.GetOk("account_name")
if !argSet {
return 0, fmt.Errorf("Either non-empty account name or valid account ID must be specified")
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
apiResp, err := controller.decortAPICall("POST", AccountsListAPI, urlValues)
if err != nil { if err != nil {
return 0, err return nil, err
} }
model := AccountsListResp{} err = json.Unmarshal([]byte(accountRaw), &account)
err = json.Unmarshal([]byte(apiResp), &model)
if err != nil { if err != nil {
return 0, err return nil, err
}
log.Debugf("utilityGetAccountIdBySchema: traversing decoded Json of length %d", len(model))
for index, item := range model {
// need to match Account by name
if item.Name == accName.(string) {
log.Debugf("utilityGetAccountIdBySchema: match Account name %q / ID %d at index %d",
item.Name, item.ID, index)
return item.ID, nil
}
} }
return 0, fmt.Errorf("Cannot find account %q for the current user. Check account name and your access rights", accName.(string)) return account, nil
} }

@ -25,7 +25,6 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
package decort package decort
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url" "net/url"
@ -36,7 +35,6 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
) )
func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
// This function tries to locate Disk by one of the following algorithms depending on // This function tries to locate Disk by one of the following algorithms depending on
// the parameters passed: // the parameters passed:
@ -64,7 +62,7 @@ func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, er
if err != nil || theId <= 0 { if err != nil || theId <= 0 {
diskId, argSet := d.GetOk("disk_id") diskId, argSet := d.GetOk("disk_id")
if argSet { if argSet {
theId =diskId.(int) theId = diskId.(int)
idSet = true idSet = true
} }
} else { } else {
@ -92,12 +90,8 @@ func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, er
// Valid account ID is required to locate disks // Valid account ID is required to locate disks
// obtain Account ID by account name - it should not be zero on success // obtain Account ID by account name - it should not be zero on success
validatedAccountId, err := utilityGetAccountIdBySchema(d, m)
if err != nil {
return "", err
}
urlValues.Add("accountId", fmt.Sprintf("%d", validatedAccountId)) urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
diskFacts, err := controller.decortAPICall("POST", DisksListAPI, urlValues) diskFacts, err := controller.decortAPICall("POST", DisksListAPI, urlValues)
if err != nil { if err != nil {
return "", err return "", err
@ -119,17 +113,17 @@ func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, er
log.Debugf("utilityDiskCheckPresence: index %d, matched disk name %q", index, item.Name) log.Debugf("utilityDiskCheckPresence: index %d, matched disk name %q", index, item.Name)
// we found the disk we need - not get detailed information via API call to disks/get // we found the disk we need - not get detailed information via API call to disks/get
/* /*
// TODO: this may not be optimal as it initiates one extra call to the DECORT controller // TODO: this may not be optimal as it initiates one extra call to the DECORT controller
// in spite of the fact that we already have all required information about the disk in // in spite of the fact that we already have all required information about the disk in
// item variable // item variable
// //
get_urlValues := &url.Values{} get_urlValues := &url.Values{}
get_urlValues.Add("diskId", fmt.Sprintf("%d", item.ID)) get_urlValues.Add("diskId", fmt.Sprintf("%d", item.ID))
diskFacts, err = controller.decortAPICall("POST", DisksGetAPI, get_urlValues) diskFacts, err = controller.decortAPICall("POST", DisksGetAPI, get_urlValues)
if err != nil { if err != nil {
return "", err return "", err
} }
return diskFacts, nil return diskFacts, nil
*/ */
reencodedItem, err := json.Marshal(item) reencodedItem, err := json.Marshal(item)
if err != nil { if err != nil {

@ -124,10 +124,6 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
// Valid account ID is required to locate a resource group // Valid account ID is required to locate a resource group
// obtain Account ID by account name - it should not be zero on success // obtain Account ID by account name - it should not be zero on success
validatedAccountId, err := utilityGetAccountIdBySchema(d, m)
if err != nil {
return "", err
}
urlValues.Add("includedeleted", "false") urlValues.Add("includedeleted", "false")
apiResp, err := controller.decortAPICall("POST", ResgroupListAPI, urlValues) apiResp, err := controller.decortAPICall("POST", ResgroupListAPI, urlValues)
@ -145,7 +141,7 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
log.Debugf("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 {
// match by RG name & account ID // match by RG name & account ID
if item.Name == rgName.(string) && item.AccountID == validatedAccountId { if item.Name == rgName.(string) && item.AccountID == d.Get("account_id").(int) {
log.Debugf("utilityResgroupCheckPresence: match RG name %s / ID %d, account ID %d at index %d", log.Debugf("utilityResgroupCheckPresence: match RG name %s / ID %d, account ID %d at index %d",
item.Name, item.ID, item.AccountID, index) item.Name, item.ID, item.AccountID, index)
@ -163,7 +159,7 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
} }
} }
return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, validatedAccountId) return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, d.Get("account_id").(int))
} }
func utilityResgroupGetDefaultGridID() (interface{}, error) { func utilityResgroupGetDefaultGridID() (interface{}, error) {
@ -172,4 +168,4 @@ func utilityResgroupGetDefaultGridID() (interface{}, error) {
} }
return "", fmt.Errorf("utilityResgroupGetDefaultGridID: invalid default Grid ID %d", DefaultGridID) return "", fmt.Errorf("utilityResgroupGetDefaultGridID: invalid default Grid ID %d", DefaultGridID)
} }

@ -25,6 +25,7 @@
- account_disks_list - account_disks_list
- account_vins_list - account_vins_list
- account_audits_list - account_audits_list
- account
- resources: - resources:
- image - image
- virtual_image - virtual_image

@ -0,0 +1,39 @@
/*
Пример использования
Получение информации об аккаунте
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_account" "a" {
#id аккаунта
#обязательный параметр
#тип - число
account_id = 28096
}
output "test" {
value = data.decort_account.a
}
Loading…
Cancel
Save