4.0.0
This commit is contained in:
@@ -119,13 +119,13 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"meta": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
// "meta": {
|
||||
// Type: schema.TypeList,
|
||||
// Computed: true,
|
||||
// Elem: &schema.Schema{
|
||||
// Type: schema.TypeString,
|
||||
// },
|
||||
// },
|
||||
"acl": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -234,10 +234,10 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"service_account": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
// "service_account": {
|
||||
// Type: schema.TypeBool,
|
||||
// Computed: true,
|
||||
// },
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
|
||||
@@ -218,13 +218,13 @@ func resourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"meta": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
// "meta": {
|
||||
// Type: schema.TypeList,
|
||||
// Computed: true,
|
||||
// Elem: &schema.Schema{
|
||||
// Type: schema.TypeString,
|
||||
// },
|
||||
// },
|
||||
"acl": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
@@ -293,10 +293,10 @@ func resourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"service_account": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
// "service_account": {
|
||||
// Type: schema.TypeBool,
|
||||
// Computed: true,
|
||||
// },
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
|
||||
@@ -33,12 +33,11 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
)
|
||||
|
||||
func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -47,51 +46,12 @@ func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interf
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("dc_location", acc.DCLocation)
|
||||
d.Set("resources", flattenAccResources(acc.Resources))
|
||||
d.Set("ckey", acc.CKey)
|
||||
d.Set("meta", flattens.FlattenMeta(acc.Meta))
|
||||
d.Set("acl", flattenAccAcl(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)
|
||||
d.SetId(strconv.FormatUint(acc.ID, 10))
|
||||
flattenDataAccount(d, acc)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, acls := range acls {
|
||||
temp := map[string]interface{}{
|
||||
"explicit": acls.IsExplicit,
|
||||
"guid": acls.Guid,
|
||||
"right": acls.Rights,
|
||||
"status": acls.Status,
|
||||
"type": acls.Type,
|
||||
"user_group_id": acls.UgroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func DataSourceAccount() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
@@ -40,22 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenAccountAuditsList(aal AccountAuditsList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, aa := range aal {
|
||||
temp := map[string]interface{}{
|
||||
"call": aa.Call,
|
||||
"responsetime": aa.ResponseTime,
|
||||
"statuscode": aa.StatusCode,
|
||||
"timestamp": aa.Timestamp,
|
||||
"user": aa.User,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func dataSourceAccountAuditsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
accountAuditsList, err := utilityAccountAuditsListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
@@ -40,37 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenAccountComputesList(acl AccountComputesList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, acc := range acl {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": acc.AccountId,
|
||||
"account_name": acc.AccountName,
|
||||
"cpus": acc.CPUs,
|
||||
"created_by": acc.CreatedBy,
|
||||
"created_time": acc.CreatedTime,
|
||||
"deleted_by": acc.DeletedBy,
|
||||
"deleted_time": acc.DeletedTime,
|
||||
"compute_id": acc.ComputeId,
|
||||
"compute_name": acc.ComputeName,
|
||||
"ram": acc.RAM,
|
||||
"registered": acc.Registered,
|
||||
"rg_id": acc.RgId,
|
||||
"rg_name": acc.RgName,
|
||||
"status": acc.Status,
|
||||
"tech_status": acc.TechStatus,
|
||||
"total_disks_size": acc.TotalDisksSize,
|
||||
"updated_by": acc.UpdatedBy,
|
||||
"updated_time": acc.UpdatedTime,
|
||||
"user_managed": acc.UserManaged,
|
||||
"vins_connected": acc.VinsConnected,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func dataSourceAccountComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
accountComputesList, err := utilityAccountComputesListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
@@ -39,23 +39,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenAccountDisksList(adl AccountDisksList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, ad := range adl {
|
||||
temp := map[string]interface{}{
|
||||
"disk_id": ad.ID,
|
||||
"disk_name": ad.Name,
|
||||
"pool_name": ad.Pool,
|
||||
"sep_id": ad.SepId,
|
||||
"size_max": ad.SizeMax,
|
||||
"type": ad.Type,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func dataSourceAccountDisksListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
accountDisksList, err := utilityAccountDisksListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
@@ -40,38 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenAccountFlipGroupsList(afgl AccountFlipGroupsList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, afg := range afgl {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": afg.AccountId,
|
||||
"client_type": afg.ClientType,
|
||||
"conn_type": afg.ConnType,
|
||||
"created_by": afg.CreatedBy,
|
||||
"created_time": afg.CreatedTime,
|
||||
"default_gw": afg.DefaultGW,
|
||||
"deleted_by": afg.DeletedBy,
|
||||
"deleted_time": afg.DeletedTime,
|
||||
"desc": afg.Desc,
|
||||
"gid": afg.GID,
|
||||
"guid": afg.GUID,
|
||||
"fg_id": afg.ID,
|
||||
"ip": afg.IP,
|
||||
"milestones": afg.Milestones,
|
||||
"fg_name": afg.Name,
|
||||
"net_id": afg.NetID,
|
||||
"net_type": afg.NetType,
|
||||
"netmask": afg.NetMask,
|
||||
"status": afg.Status,
|
||||
"updated_by": afg.UpdatedBy,
|
||||
"updated_time": afg.UpdatedTime,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func dataSourceAccountFlipGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
accountFlipGroupsList, err := utilityAccountFlipGroupsListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
@@ -38,83 +38,8 @@ import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
)
|
||||
|
||||
func flattenRgAcl(rgAcls []AccountAclRecord) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, rgAcl := range rgAcls {
|
||||
temp := map[string]interface{}{
|
||||
"explicit": rgAcl.IsExplicit,
|
||||
"guid": rgAcl.Guid,
|
||||
"right": rgAcl.Rights,
|
||||
"status": rgAcl.Status,
|
||||
"type": rgAcl.Type,
|
||||
"user_group_id": rgAcl.UgroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccountList(al AccountList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, acc := range al {
|
||||
temp := map[string]interface{}{
|
||||
"dc_location": acc.DCLocation,
|
||||
"ckey": acc.CKey,
|
||||
"meta": flattens.FlattenMeta(acc.Meta),
|
||||
|
||||
"acl": flattenRgAcl(acc.Acl),
|
||||
|
||||
"company": acc.Company,
|
||||
"companyurl": acc.CompanyUrl,
|
||||
"created_by": acc.CreatedBy,
|
||||
|
||||
"created_time": acc.CreatedTime,
|
||||
|
||||
"deactivation_time": acc.DeactiovationTime,
|
||||
"deleted_by": acc.DeletedBy,
|
||||
|
||||
"deleted_time": acc.DeletedTime,
|
||||
|
||||
"displayname": acc.DisplayName,
|
||||
"guid": acc.GUID,
|
||||
|
||||
"account_id": acc.ID,
|
||||
"account_name": acc.Name,
|
||||
|
||||
"resource_limits": flattenRgResourceLimits(acc.ResourceLimits),
|
||||
"send_access_emails": acc.SendAccessEmails,
|
||||
"service_account": acc.ServiceAccount,
|
||||
|
||||
"status": acc.Status,
|
||||
"updated_time": acc.UpdatedTime,
|
||||
|
||||
"version": acc.Version,
|
||||
"vins": acc.Vins,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"cu_c": rl.CUC,
|
||||
"cu_d": rl.CUD,
|
||||
"cu_i": rl.CUI,
|
||||
"cu_m": rl.CUM,
|
||||
"cu_np": rl.CUNP,
|
||||
"gpu_units": rl.GpuUnits,
|
||||
}
|
||||
res = append(res, temp)
|
||||
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func dataSourceAccountListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
accountList, err := utilityAccountListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
@@ -40,75 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenAccountRGList(argl AccountRGList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, arg := range argl {
|
||||
temp := map[string]interface{}{
|
||||
"computes": flattenAccRGComputes(arg.Computes),
|
||||
"resources": flattenAccRGResources(arg.Resources),
|
||||
"created_by": arg.CreatedBy,
|
||||
"created_time": arg.CreatedTime,
|
||||
"deleted_by": arg.DeletedBy,
|
||||
"deleted_time": arg.DeletedTime,
|
||||
"rg_id": arg.RGID,
|
||||
"milestones": arg.Milestones,
|
||||
"rg_name": arg.RGName,
|
||||
"status": arg.Status,
|
||||
"updated_by": arg.UpdatedBy,
|
||||
"updated_time": arg.UpdatedTime,
|
||||
"vinses": arg.Vinses,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func flattenAccRGComputes(argc AccountRGComputes) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"started": argc.Started,
|
||||
"stopped": argc.Stopped,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccRGResources(argr AccountRGResources) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"consumed": flattenAccResource(argr.Consumed),
|
||||
"limits": flattenAccResource(argr.Limits),
|
||||
"reserved": flattenAccResource(argr.Reserved),
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccResources(r Resources) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"current": flattenAccResource(r.Current),
|
||||
"reserved": flattenAccResource(r.Reserved),
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
func dataSourceAccountRGListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
accountRGList, err := utilityAccountRGListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
@@ -40,34 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenAccountVinsList(avl AccountVinsList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, av := range avl {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": av.AccountId,
|
||||
"account_name": av.AccountName,
|
||||
"computes": av.Computes,
|
||||
"created_by": av.CreatedBy,
|
||||
"created_time": av.CreatedTime,
|
||||
"deleted_by": av.DeletedBy,
|
||||
"deleted_time": av.DeletedTime,
|
||||
"external_ip": av.ExternalIP,
|
||||
"vin_id": av.ID,
|
||||
"vin_name": av.Name,
|
||||
"network": av.Network,
|
||||
"pri_vnf_dev_id": av.PriVnfDevId,
|
||||
"rg_id": av.RgId,
|
||||
"rg_name": av.RgName,
|
||||
"status": av.Status,
|
||||
"updated_by": av.UpdatedBy,
|
||||
"updated_time": av.UpdatedTime,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func dataSourceAccountVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
accountVinsList, err := utilityAccountVinsListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
363
internal/service/cloudbroker/account/flattens.go
Normal file
363
internal/service/cloudbroker/account/flattens.go
Normal file
@@ -0,0 +1,363 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
)
|
||||
|
||||
func flattenResourceAccount(d *schema.ResourceData, acc *account.RecordAccount) {
|
||||
d.Set("dc_location", acc.DCLocation)
|
||||
d.Set("resources", flattenAccResources(acc.Resources))
|
||||
d.Set("ckey", acc.CKey)
|
||||
d.Set("acl", flattenAccAcl(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.DeactivationTime)
|
||||
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("status", acc.Status)
|
||||
d.Set("updated_time", acc.UpdatedTime)
|
||||
d.Set("version", acc.Version)
|
||||
d.Set("vins", acc.VINS)
|
||||
}
|
||||
|
||||
func flattenDataAccount(d *schema.ResourceData, acc *account.RecordAccount) {
|
||||
d.Set("dc_location", acc.DCLocation)
|
||||
d.Set("resources", flattenAccResources(acc.Resources))
|
||||
d.Set("ckey", acc.CKey)
|
||||
// d.Set("meta", flattens.FlattenMeta(acc.))
|
||||
d.Set("acl", flattenAccAcl(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.DeactivationTime)
|
||||
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)
|
||||
|
||||
}
|
||||
|
||||
func flattenAccountRGList(argl account.ListRG) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, arg := range argl {
|
||||
temp := map[string]interface{}{
|
||||
"computes": flattenAccRGComputes(arg.Computes),
|
||||
"resources": flattenAccRGResources(arg.Resources),
|
||||
"created_by": arg.CreatedBy,
|
||||
"created_time": arg.CreatedTime,
|
||||
"deleted_by": arg.DeletedBy,
|
||||
"deleted_time": arg.DeletedTime,
|
||||
"rg_id": arg.ID,
|
||||
"milestones": arg.Milestones,
|
||||
"rg_name": arg.Name,
|
||||
"status": arg.Status,
|
||||
"updated_by": arg.UpdatedBy,
|
||||
"updated_time": arg.UpdatedTime,
|
||||
"vinses": arg.VINSes,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func flattenAccRGComputes(argc account.Computes) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"started": argc.Started,
|
||||
"stopped": argc.Stopped,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccRGResources(argr account.RGResuorces) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"consumed": flattenAccConsumed(argr.Consumed),
|
||||
"limits": flattenAccLimits(argr.Limits),
|
||||
"reserved": flattenAccResource(argr.Reserved),
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccResources(r account.RecordResources) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"current": flattenAccResource(r.Current),
|
||||
"reserved": flattenAccResource(r.Reserved),
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccConsumed(c account.Consumed) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"cpu": c.CPU,
|
||||
"disksize": c.DiskSize,
|
||||
"extips": c.ExtIPs,
|
||||
"exttraffic": c.ExtTraffic,
|
||||
"gpu": c.GPU,
|
||||
"ram": c.RAM,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccLimits(l account.Limits) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"cpu": l.CPU,
|
||||
"disksize": l.DiskSize,
|
||||
"extips": l.ExtIPs,
|
||||
"exttraffic": l.ExtTraffic,
|
||||
"gpu": l.GPU,
|
||||
"ram": l.RAM,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccResource(r account.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
|
||||
}
|
||||
|
||||
func flattenAccAcl(acls []account.ACL) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, acls := range acls {
|
||||
temp := map[string]interface{}{
|
||||
"explicit": acls.Explicit,
|
||||
"guid": acls.GUID,
|
||||
"right": acls.Right,
|
||||
"status": acls.Status,
|
||||
"type": acls.Type,
|
||||
"user_group_id": acls.UserGroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenRgResourceLimits(rl account.ResourceLimits) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"cu_c": rl.CuC,
|
||||
"cu_d": rl.CuD,
|
||||
"cu_i": rl.CuI,
|
||||
"cu_m": rl.CuM,
|
||||
"cu_np": rl.CuNP,
|
||||
"gpu_units": rl.GPUUnits,
|
||||
}
|
||||
res = append(res, temp)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenRgAcl(rgAcls []account.ACL) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, rgAcl := range rgAcls {
|
||||
temp := map[string]interface{}{
|
||||
"explicit": rgAcl.Explicit,
|
||||
"guid": rgAcl.GUID,
|
||||
"right": rgAcl.Right,
|
||||
"status": rgAcl.Status,
|
||||
"type": rgAcl.Type,
|
||||
"user_group_id": rgAcl.UserGroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccountList(al account.ListAccounts) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, acc := range al {
|
||||
temp := map[string]interface{}{
|
||||
"dc_location": acc.DCLocation,
|
||||
"ckey": acc.CKey,
|
||||
"meta": flattens.FlattenMeta(acc.Meta),
|
||||
|
||||
"acl": flattenRgAcl(acc.ACL),
|
||||
|
||||
"company": acc.Company,
|
||||
"companyurl": acc.CompanyURL,
|
||||
"created_by": acc.CreatedBy,
|
||||
|
||||
"created_time": acc.CreatedTime,
|
||||
|
||||
"deactivation_time": acc.DeactivationTime,
|
||||
"deleted_by": acc.DeletedBy,
|
||||
|
||||
"deleted_time": acc.DeletedTime,
|
||||
|
||||
"displayname": acc.DisplayName,
|
||||
"guid": acc.GUID,
|
||||
|
||||
"account_id": acc.ID,
|
||||
"account_name": acc.Name,
|
||||
|
||||
"resource_limits": flattenRgResourceLimits(acc.ResourceLimits),
|
||||
"send_access_emails": acc.SendAccessEmails,
|
||||
// "service_account": acc.ServiceAccount,
|
||||
|
||||
"status": acc.Status,
|
||||
"updated_time": acc.UpdatedTime,
|
||||
|
||||
"version": acc.Version,
|
||||
"vins": acc.VINS,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccountAuditsList(aal account.ListAudits) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, aa := range aal {
|
||||
temp := map[string]interface{}{
|
||||
"call": aa.Call,
|
||||
"responsetime": aa.ResponseTime,
|
||||
"statuscode": aa.StatusCode,
|
||||
"timestamp": aa.Timestamp,
|
||||
"user": aa.User,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccountComputesList(acl account.ListComputes) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, acc := range acl {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": acc.AccountID,
|
||||
"account_name": acc.AccountName,
|
||||
"cpus": acc.CPUs,
|
||||
"created_by": acc.CreatedBy,
|
||||
"created_time": acc.CreatedTime,
|
||||
"deleted_by": acc.DeletedBy,
|
||||
"deleted_time": acc.DeletedTime,
|
||||
"compute_id": acc.ID,
|
||||
"compute_name": acc.Name,
|
||||
"ram": acc.RAM,
|
||||
"registered": acc.Registered,
|
||||
"rg_id": acc.RGID,
|
||||
"rg_name": acc.RgName,
|
||||
"status": acc.Status,
|
||||
"tech_status": acc.TechStatus,
|
||||
"total_disks_size": acc.TotalDisksSize,
|
||||
"updated_by": acc.UpdatedBy,
|
||||
"updated_time": acc.UpdatedTime,
|
||||
"user_managed": acc.UserManaged,
|
||||
"vins_connected": acc.VINSConnected,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccountDisksList(adl account.ListDisks) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, ad := range adl {
|
||||
temp := map[string]interface{}{
|
||||
"disk_id": ad.ID,
|
||||
"disk_name": ad.Name,
|
||||
"pool_name": ad.Pool,
|
||||
"sep_id": ad.SepID,
|
||||
"size_max": ad.SizeMax,
|
||||
"type": ad.Type,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccountFlipGroupsList(afgl account.ListFLIPGroups) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, afg := range afgl {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": afg.AccountID,
|
||||
"client_type": afg.ClientType,
|
||||
"conn_type": afg.ConnType,
|
||||
"created_by": afg.CreatedBy,
|
||||
"created_time": afg.CreatedTime,
|
||||
"default_gw": afg.DefaultGW,
|
||||
"deleted_by": afg.DeletedBy,
|
||||
"deleted_time": afg.DeletedTime,
|
||||
"desc": afg.Description,
|
||||
"gid": afg.GID,
|
||||
"guid": afg.GUID,
|
||||
"fg_id": afg.ID,
|
||||
"ip": afg.IP,
|
||||
"milestones": afg.Milestones,
|
||||
"fg_name": afg.Name,
|
||||
"net_id": afg.NetID,
|
||||
"net_type": afg.NetType,
|
||||
"netmask": afg.Netmask,
|
||||
"status": afg.Status,
|
||||
"updated_by": afg.UpdatedBy,
|
||||
"updated_time": afg.UpdatedTime,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccountVinsList(avl account.ListVINS) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, av := range avl {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": av.AccountID,
|
||||
"account_name": av.AccountName,
|
||||
"computes": av.Computes,
|
||||
"created_by": av.CreatedBy,
|
||||
"created_time": av.CreatedTime,
|
||||
"deleted_by": av.DeletedBy,
|
||||
"deleted_time": av.DeletedTime,
|
||||
"external_ip": av.ExternalIP,
|
||||
"vin_id": av.ID,
|
||||
"vin_name": av.Name,
|
||||
"network": av.Network,
|
||||
"pri_vnf_dev_id": av.PriVNFDevID,
|
||||
"rg_id": av.RGID,
|
||||
"rg_name": av.RGName,
|
||||
"status": av.Status,
|
||||
"updated_by": av.UpdatedBy,
|
||||
"updated_time": av.UpdatedTime,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -33,95 +33,94 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceAccountCreate")
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := account.CreateRequest{}
|
||||
|
||||
urlValues.Add("name", d.Get("account_name").(string))
|
||||
urlValues.Add("username", d.Get("username").(string))
|
||||
req.Name = d.Get("account_name").(string)
|
||||
req.Username = d.Get("username").(string)
|
||||
|
||||
if emailaddress, ok := d.GetOk("emailaddress"); ok {
|
||||
urlValues.Add("emailaddress", emailaddress.(string))
|
||||
req.EmailAddress = emailaddress.(string)
|
||||
}
|
||||
if sendAccessEmails, ok := d.GetOk("send_access_emails"); ok {
|
||||
urlValues.Add("sendAccessEmails", strconv.FormatBool(sendAccessEmails.(bool)))
|
||||
req.SendAccessEmails = sendAccessEmails.(bool)
|
||||
}
|
||||
if resLimits, ok := d.GetOk("resource_limits"); ok {
|
||||
resLimit := resLimits.([]interface{})[0]
|
||||
resLimitConv := resLimit.(map[string]interface{})
|
||||
if resLimitConv["cu_m"] != nil {
|
||||
maxMemCap := int(resLimitConv["cu_m"].(float64))
|
||||
maxMemCap := int64(resLimitConv["cu_m"].(float64))
|
||||
if maxMemCap == 0 {
|
||||
urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1))
|
||||
req.MaxMemoryCapacity = -1
|
||||
} else {
|
||||
urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap))
|
||||
req.MaxMemoryCapacity = maxMemCap
|
||||
}
|
||||
}
|
||||
if resLimitConv["cu_d"] != nil {
|
||||
maxDiskCap := int(resLimitConv["cu_d"].(float64))
|
||||
maxDiskCap := int64(resLimitConv["cu_d"].(float64))
|
||||
if maxDiskCap == 0 {
|
||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1))
|
||||
req.MaxVDiskCapacity = -1
|
||||
} else {
|
||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap))
|
||||
req.MaxVDiskCapacity = maxDiskCap
|
||||
}
|
||||
}
|
||||
if resLimitConv["cu_c"] != nil {
|
||||
maxCPUCap := int(resLimitConv["cu_c"].(float64))
|
||||
maxCPUCap := int64(resLimitConv["cu_c"].(float64))
|
||||
if maxCPUCap == 0 {
|
||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(-1))
|
||||
req.MaxCPUCapacity = -1
|
||||
} else {
|
||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap))
|
||||
req.MaxCPUCapacity = maxCPUCap
|
||||
}
|
||||
|
||||
}
|
||||
if resLimitConv["cu_i"] != nil {
|
||||
maxNumPublicIP := int(resLimitConv["cu_i"].(float64))
|
||||
maxNumPublicIP := int64(resLimitConv["cu_i"].(float64))
|
||||
if maxNumPublicIP == 0 {
|
||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(-1))
|
||||
req.MaxNumPublicIP = -1
|
||||
} else {
|
||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP))
|
||||
req.MaxNumPublicIP = maxNumPublicIP
|
||||
}
|
||||
|
||||
}
|
||||
if resLimitConv["cu_np"] != nil {
|
||||
maxNP := int(resLimitConv["cu_np"].(float64))
|
||||
maxNP := int64(resLimitConv["cu_np"].(float64))
|
||||
if maxNP == 0 {
|
||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1))
|
||||
req.MaxNetworkPeerTransfer = -1
|
||||
} else {
|
||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP))
|
||||
req.MaxNetworkPeerTransfer = maxNP
|
||||
}
|
||||
|
||||
}
|
||||
if resLimitConv["gpu_units"] != nil {
|
||||
gpuUnits := int(resLimitConv["gpu_units"].(float64))
|
||||
gpuUnits := int64(resLimitConv["gpu_units"].(float64))
|
||||
if gpuUnits == 0 {
|
||||
urlValues.Add("gpu_units", strconv.Itoa(-1))
|
||||
req.GPUUnits = -1
|
||||
} else {
|
||||
urlValues.Add("gpu_units", strconv.Itoa(gpuUnits))
|
||||
req.GPUUnits = gpuUnits
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
accountId, err := c.DecortAPICall(ctx, "POST", accountCreateAPI, urlValues)
|
||||
accountId, err := c.CloudBroker().Account().Create(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(accountId)
|
||||
d.SetId(strconv.FormatUint(accountId, 10))
|
||||
d.Set("account_id", accountId)
|
||||
|
||||
diagnostics := resourceAccountRead(ctx, d, m)
|
||||
@@ -130,19 +129,24 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
}
|
||||
|
||||
if enable, ok := d.GetOk("enable"); ok {
|
||||
api := accountDisableAPI
|
||||
enable := enable.(bool)
|
||||
if enable {
|
||||
api = accountEnableAPI
|
||||
req := account.EnableRequest{
|
||||
AccountID: accountId,
|
||||
}
|
||||
_, err := c.CloudBroker().Account().Enable(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
req := account.DisableRequest{
|
||||
AccountID: accountId,
|
||||
}
|
||||
_, err := c.CloudBroker().Account().Disable(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if users, ok := d.GetOk("users"); ok {
|
||||
@@ -151,15 +155,16 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
if len(addedUsers) > 0 {
|
||||
for _, user := range addedUsers {
|
||||
userConv := user.(map[string]interface{})
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("userId", userConv["user_id"].(string))
|
||||
urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountAddUserAPI, urlValues)
|
||||
req := account.AddUserRequest{
|
||||
AccountID: accountId,
|
||||
Username: userConv["user_id"].(string),
|
||||
AccessType: userConv["access_type"].(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Account().AddUser(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,34 +176,12 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
log.Debugf("resourceAccountRead")
|
||||
|
||||
acc, err := utilityAccountCheckPresence(ctx, d, m)
|
||||
if acc == nil {
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("dc_location", acc.DCLocation)
|
||||
d.Set("resources", flattenAccResources(acc.Resources))
|
||||
d.Set("ckey", acc.CKey)
|
||||
d.Set("meta", flattens.FlattenMeta(acc.Meta))
|
||||
d.Set("acl", flattenAccAcl(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)
|
||||
flattenResourceAccount(d, acc)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -206,58 +189,65 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceAccountDelete")
|
||||
|
||||
account, err := utilityAccountCheckPresence(ctx, d, m)
|
||||
if account == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", accountDeleteAPI, urlValues)
|
||||
accountData, err := utilityAccountCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := account.DeleteRequest{
|
||||
AccountID: accountData.ID,
|
||||
Permanently: d.Get("permanently").(bool),
|
||||
}
|
||||
|
||||
_, err = c.CloudBroker().Account().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceAccountEdit")
|
||||
func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceAccountUpdate")
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
if d.HasChange("enable") {
|
||||
api := accountDisableAPI
|
||||
enable := d.Get("enable").(bool)
|
||||
if enable {
|
||||
api = accountEnableAPI
|
||||
}
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
acc, err := utilityAccountCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if d.HasChange("account_name") {
|
||||
urlValues.Add("name", d.Get("account_name").(string))
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
if d.HasChange("enable") {
|
||||
enable := d.Get("enable").(bool)
|
||||
if enable {
|
||||
req := account.EnableRequest{
|
||||
AccountID: acc.ID,
|
||||
}
|
||||
_, err := c.CloudBroker().Account().Enable(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
req := account.DisableRequest{
|
||||
AccountID: acc.ID,
|
||||
}
|
||||
_, err := c.CloudBroker().Account().Disable(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
updateReq := account.UpdateRequest{AccountID: acc.ID}
|
||||
hasChange := false
|
||||
|
||||
if d.HasChange("account_name") {
|
||||
updateReq.Name = d.Get("account_name").(string)
|
||||
|
||||
hasChange = true
|
||||
}
|
||||
if d.HasChange("resource_limits") {
|
||||
resLimit := d.Get("resource_limits").([]interface{})[0]
|
||||
@@ -266,85 +256,81 @@ func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
if resLimitConv["cu_m"] != nil {
|
||||
maxMemCap := int(resLimitConv["cu_m"].(float64))
|
||||
if maxMemCap == 0 {
|
||||
urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1))
|
||||
updateReq.MaxMemoryCapacity = -1
|
||||
} else {
|
||||
urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap))
|
||||
updateReq.MaxMemoryCapacity = int64(maxMemCap)
|
||||
}
|
||||
}
|
||||
if resLimitConv["cu_d"] != nil {
|
||||
maxDiskCap := int(resLimitConv["cu_d"].(float64))
|
||||
if maxDiskCap == 0 {
|
||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1))
|
||||
updateReq.MaxVDiskCapacity = -1
|
||||
} else {
|
||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap))
|
||||
updateReq.MaxVDiskCapacity = int64(maxDiskCap)
|
||||
}
|
||||
}
|
||||
if resLimitConv["cu_c"] != nil {
|
||||
maxCPUCap := int(resLimitConv["cu_c"].(float64))
|
||||
if maxCPUCap == 0 {
|
||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(-1))
|
||||
updateReq.MaxCPUCapacity = -1
|
||||
} else {
|
||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap))
|
||||
updateReq.MaxCPUCapacity = int64(maxCPUCap)
|
||||
}
|
||||
|
||||
}
|
||||
if resLimitConv["cu_i"] != nil {
|
||||
maxNumPublicIP := int(resLimitConv["cu_i"].(float64))
|
||||
if maxNumPublicIP == 0 {
|
||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(-1))
|
||||
updateReq.MaxNumPublicIP = -1
|
||||
} else {
|
||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP))
|
||||
updateReq.MaxNumPublicIP = int64(maxNumPublicIP)
|
||||
}
|
||||
|
||||
}
|
||||
if resLimitConv["cu_np"] != nil {
|
||||
maxNP := int(resLimitConv["cu_np"].(float64))
|
||||
if maxNP == 0 {
|
||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1))
|
||||
updateReq.MaxNetworkPeerTransfer = -1
|
||||
} else {
|
||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP))
|
||||
updateReq.MaxNetworkPeerTransfer = int64(maxNP)
|
||||
}
|
||||
|
||||
}
|
||||
if resLimitConv["gpu_units"] != nil {
|
||||
gpuUnits := int(resLimitConv["gpu_units"].(float64))
|
||||
if gpuUnits == 0 {
|
||||
urlValues.Add("gpu_units", strconv.Itoa(-1))
|
||||
updateReq.GPUUnits = -1
|
||||
} else {
|
||||
urlValues.Add("gpu_units", strconv.Itoa(gpuUnits))
|
||||
updateReq.GPUUnits = int64(gpuUnits)
|
||||
}
|
||||
}
|
||||
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
hasChange = true
|
||||
}
|
||||
|
||||
if d.HasChange("send_access_emails") {
|
||||
urlValues.Add("sendAccessEmails", strconv.FormatBool(d.Get("send_access_emails").(bool)))
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues)
|
||||
updateReq.SendAccessEmails = d.Get("send_access_emails").(bool)
|
||||
hasChange = true
|
||||
}
|
||||
|
||||
if hasChange {
|
||||
_, err := c.CloudBroker().Account().Update(ctx, updateReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("restore") {
|
||||
restore := d.Get("restore").(bool)
|
||||
if restore {
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountRestoreAPI, urlValues)
|
||||
req := account.RestoreRequest{
|
||||
AccountID: acc.ID,
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Account().Restore(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,45 +360,48 @@ func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
if len(deletedUsers) > 0 {
|
||||
for _, user := range deletedUsers {
|
||||
userConv := user.(map[string]interface{})
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("userId", userConv["user_id"].(string))
|
||||
urlValues.Add("recursivedelete", strconv.FormatBool(userConv["recursive_delete"].(bool)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountDeleteUserAPI, urlValues)
|
||||
req := account.DeleteUserRequest{
|
||||
AccountID: acc.ID,
|
||||
UserName: userConv["user_id"].(string),
|
||||
RecursiveDelete: userConv["recursive_delete"].(bool),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Account().DeleteUser(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
}
|
||||
|
||||
if len(addedUsers) > 0 {
|
||||
for _, user := range addedUsers {
|
||||
userConv := user.(map[string]interface{})
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("userId", userConv["user_id"].(string))
|
||||
urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountAddUserAPI, urlValues)
|
||||
req := account.AddUserRequest{
|
||||
AccountID: acc.ID,
|
||||
Username: userConv["user_id"].(string),
|
||||
AccessType: strings.ToUpper(userConv["access_type"].(string)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Account().AddUser(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
}
|
||||
|
||||
if len(updatedUsers) > 0 {
|
||||
for _, user := range updatedUsers {
|
||||
userConv := user.(map[string]interface{})
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("userId", userConv["user_id"].(string))
|
||||
urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountUpdateUserAPI, urlValues)
|
||||
req := account.UpdateUserRequest{
|
||||
AccountID: acc.ID,
|
||||
UserID: userConv["user_id"].(string),
|
||||
AccessType: strings.ToUpper(userConv["access_type"].(string)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Account().UpdateUser(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,7 +440,7 @@ func ResourceAccount() *schema.Resource {
|
||||
|
||||
CreateContext: resourceAccountCreate,
|
||||
ReadContext: resourceAccountRead,
|
||||
UpdateContext: resourceAccountEdit,
|
||||
UpdateContext: resourceAccountUpdate,
|
||||
DeleteContext: resourceAccountDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -33,34 +33,28 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*AccountWithResources, error) {
|
||||
account := &AccountWithResources{}
|
||||
func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*account.RecordAccount, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := account.GetRequest{}
|
||||
|
||||
if (strconv.Itoa(d.Get("account_id").(int))) != "0" {
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
req.AccountID = uint64(d.Get("account_id").(int))
|
||||
} else {
|
||||
urlValues.Add("accountId", d.Id())
|
||||
id, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req.AccountID = id
|
||||
}
|
||||
|
||||
log.Debugf("utilityAccountCheckPresence: load account")
|
||||
accountRaw, err := c.DecortAPICall(ctx, "POST", accountGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountRaw), &account)
|
||||
account, err := c.CloudBroker().Account().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,30 +33,22 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountAuditsList, error) {
|
||||
accountAuditsList := AccountAuditsList{}
|
||||
func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAudits, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
|
||||
log.Debugf("utilityAccountAuditsListCheckPresence: load account list")
|
||||
accountAuditsListRaw, err := c.DecortAPICall(ctx, "POST", accountAuditsAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := account.AuditsRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountAuditsListRaw), &accountAuditsList)
|
||||
log.Debugf("utilityAccountAuditsListCheckPresence: load account list")
|
||||
accountAuditsList, err := c.CloudBroker().Account().Audits(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,30 +33,22 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountComputesList, error) {
|
||||
accountComputesList := AccountComputesList{}
|
||||
func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListComputes, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
|
||||
log.Debugf("utilityAccountComputesListCheckPresence: load account list")
|
||||
accountComputesListRaw, err := c.DecortAPICall(ctx, "POST", accountListComputesAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := account.ListComputesRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountComputesListRaw), &accountComputesList)
|
||||
log.Debugf("utilityAccountComputesListCheckPresence: load account list")
|
||||
accountComputesList, err := c.CloudBroker().Account().ListComputes(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,35 +33,27 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountList, error) {
|
||||
accountDeletedList := AccountList{}
|
||||
func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAccounts, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := account.ListDeletedRequest{}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityAccountDeletedListCheckPresence: load")
|
||||
accountDeletedListRaw, err := c.DecortAPICall(ctx, "POST", accountListDeletedAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountDeletedListRaw), &accountDeletedList)
|
||||
accountDeletedList, err := c.CloudBroker().Account().ListDeleted(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,30 +33,22 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountDisksList, error) {
|
||||
accountDisksList := AccountDisksList{}
|
||||
func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListDisks, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
|
||||
log.Debugf("utilityAccountDisksListCheckPresence: load account list")
|
||||
accountDisksListRaw, err := c.DecortAPICall(ctx, "POST", accountListDisksAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := account.ListDisksRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountDisksListRaw), &accountDisksList)
|
||||
log.Debugf("utilityAccountDisksListCheckPresence: load account list")
|
||||
accountDisksList, err := c.CloudBroker().Account().ListDisks(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,30 +33,22 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountFlipGroupsList, error) {
|
||||
accountFlipGroupsList := AccountFlipGroupsList{}
|
||||
func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListFLIPGroups, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
|
||||
log.Debugf("utilityAccountFlipGroupsListCheckPresence")
|
||||
accountFlipGroupsListRaw, err := c.DecortAPICall(ctx, "POST", accountListFlipGroupsAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := account.ListFLIPGroupsRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountFlipGroupsListRaw), &accountFlipGroupsList)
|
||||
log.Debugf("utilityAccountFlipGroupsListCheckPresence")
|
||||
accountFlipGroupsList, err := c.CloudBroker().Account().ListFLIPGroups(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,35 +33,27 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountList, error) {
|
||||
accountList := AccountList{}
|
||||
func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListAccounts, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := account.ListRequest{}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityAccountListCheckPresence: load account list")
|
||||
accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountListRaw), &accountList)
|
||||
accountList, err := c.CloudBroker().Account().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,30 +33,22 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountRGList, error) {
|
||||
accountRGList := AccountRGList{}
|
||||
func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListRG, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
|
||||
log.Debugf("utilityAccountRGListCheckPresence: load account list")
|
||||
accountRGListRaw, err := c.DecortAPICall(ctx, "POST", accountListRGAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := account.ListRGRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountRGListRaw), &accountRGList)
|
||||
log.Debugf("utilityAccountRGListCheckPresence: load account list")
|
||||
accountRGList, err := c.CloudBroker().Account().ListRG(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,30 +33,22 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/account"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountVinsList, error) {
|
||||
accountVinsList := AccountVinsList{}
|
||||
func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (account.ListVINS, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
|
||||
log.Debugf("utilityAccountVinsListCheckPresence: load account list")
|
||||
accountVinsListRaw, err := c.DecortAPICall(ctx, "POST", accountListVinsAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := account.ListVINSRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountVinsListRaw), &accountVinsList)
|
||||
log.Debugf("utilityAccountVinsListCheckPresence: load account list")
|
||||
accountVinsList, err := c.CloudBroker().Account().ListVINS(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package disks
|
||||
|
||||
const disksCreateAPI = "/restmachine/cloudbroker/disks/create"
|
||||
const disksGetAPI = "/restmachine/cloudbroker/disks/get"
|
||||
const disksListAPI = "/restmachine/cloudbroker/disks/list"
|
||||
const disksResizeAPI = "/restmachine/cloudbroker/disks/resize2"
|
||||
const disksRenameAPI = "/restmachine/cloudbroker/disks/rename"
|
||||
const disksDeleteAPI = "/restmachine/cloudbroker/disks/delete"
|
||||
const disksIOLimitAPI = "/restmachine/cloudbroker/disks/limitIO"
|
||||
const disksRestoreAPI = "/restmachine/cloudbroker/disks/restore"
|
||||
@@ -33,7 +33,6 @@ package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
// "net/url"
|
||||
|
||||
@@ -53,52 +52,7 @@ func dataSourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
|
||||
diskAcl, _ := json.Marshal(disk.Acl)
|
||||
|
||||
d.Set("account_id", disk.AccountID)
|
||||
d.Set("account_name", disk.AccountName)
|
||||
d.Set("acl", string(diskAcl))
|
||||
d.Set("boot_partition", disk.BootPartition)
|
||||
d.Set("compute_id", disk.ComputeID)
|
||||
d.Set("compute_name", disk.ComputeName)
|
||||
d.Set("created_time", disk.CreatedTime)
|
||||
d.Set("deleted_time", disk.DeletedTime)
|
||||
d.Set("desc", disk.Desc)
|
||||
d.Set("destruction_time", disk.DestructionTime)
|
||||
d.Set("devicename", disk.DeviceName)
|
||||
d.Set("disk_path", disk.DiskPath)
|
||||
d.Set("gid", disk.GridID)
|
||||
d.Set("guid", disk.GUID)
|
||||
d.Set("disk_id", disk.ID)
|
||||
d.Set("image_id", disk.ImageID)
|
||||
d.Set("images", disk.Images)
|
||||
d.Set("iotune", flattenIOTune(disk.IOTune))
|
||||
d.Set("iqn", disk.IQN)
|
||||
d.Set("login", disk.Login)
|
||||
d.Set("milestones", disk.Milestones)
|
||||
d.Set("disk_name", disk.Name)
|
||||
d.Set("order", disk.Order)
|
||||
d.Set("params", disk.Params)
|
||||
d.Set("parent_id", disk.ParentId)
|
||||
d.Set("passwd", disk.Passwd)
|
||||
d.Set("pci_slot", disk.PciSlot)
|
||||
d.Set("pool", disk.Pool)
|
||||
d.Set("purge_attempts", disk.PurgeAttempts)
|
||||
d.Set("purge_time", disk.PurgeTime)
|
||||
d.Set("reality_device_number", disk.RealityDeviceNumber)
|
||||
d.Set("reference_id", disk.ReferenceId)
|
||||
d.Set("res_id", disk.ResID)
|
||||
d.Set("res_name", disk.ResName)
|
||||
d.Set("role", disk.Role)
|
||||
d.Set("sep_id", disk.SepID)
|
||||
d.Set("sep_type", disk.SepType)
|
||||
d.Set("size_max", disk.SizeMax)
|
||||
d.Set("size_used", disk.SizeUsed)
|
||||
d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots))
|
||||
d.Set("status", disk.Status)
|
||||
d.Set("tech_status", disk.TechStatus)
|
||||
d.Set("type", disk.Type)
|
||||
d.Set("vmid", disk.VMID)
|
||||
flattenDisk(d, disk)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -125,14 +79,6 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
|
||||
@@ -33,7 +33,6 @@ package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -41,104 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenIOTune(iot IOTune) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"read_bytes_sec": iot.ReadBytesSec,
|
||||
"read_bytes_sec_max": iot.ReadBytesSecMax,
|
||||
"read_iops_sec": iot.ReadIopsSec,
|
||||
"read_iops_sec_max": iot.ReadIopsSecMax,
|
||||
"size_iops_sec": iot.SizeIopsSec,
|
||||
"total_bytes_sec": iot.TotalBytesSec,
|
||||
"total_bytes_sec_max": iot.TotalBytesSecMax,
|
||||
"total_iops_sec": iot.TotalIopsSec,
|
||||
"total_iops_sec_max": iot.TotalIopsSecMax,
|
||||
"write_bytes_sec": iot.WriteBytesSec,
|
||||
"write_bytes_sec_max": iot.WriteBytesSecMax,
|
||||
"write_iops_sec": iot.WriteIopsSec,
|
||||
"write_iops_sec_max": iot.WriteIopsSecMax,
|
||||
}
|
||||
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenDiskList(dl DisksList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, disk := range dl {
|
||||
diskAcl, _ := json.Marshal(disk.Acl)
|
||||
temp := map[string]interface{}{
|
||||
"account_id": disk.AccountID,
|
||||
"account_name": disk.AccountName,
|
||||
"acl": string(diskAcl),
|
||||
"boot_partition": disk.BootPartition,
|
||||
"compute_id": disk.ComputeID,
|
||||
"compute_name": disk.ComputeName,
|
||||
"created_time": disk.CreatedTime,
|
||||
"deleted_time": disk.DeletedTime,
|
||||
"desc": disk.Desc,
|
||||
"destruction_time": disk.DestructionTime,
|
||||
"devicename": disk.DeviceName,
|
||||
"disk_path": disk.DiskPath,
|
||||
"gid": disk.GridID,
|
||||
"guid": disk.GUID,
|
||||
"disk_id": disk.ID,
|
||||
"image_id": disk.ImageID,
|
||||
"images": disk.Images,
|
||||
"iotune": flattenIOTune(disk.IOTune),
|
||||
"iqn": disk.IQN,
|
||||
"login": disk.Login,
|
||||
"machine_id": disk.MachineId,
|
||||
"machine_name": disk.MachineName,
|
||||
"milestones": disk.Milestones,
|
||||
"disk_name": disk.Name,
|
||||
"order": disk.Order,
|
||||
"params": disk.Params,
|
||||
"parent_id": disk.ParentId,
|
||||
"passwd": disk.Passwd,
|
||||
"pci_slot": disk.PciSlot,
|
||||
"pool": disk.Pool,
|
||||
"purge_attempts": disk.PurgeAttempts,
|
||||
"purge_time": disk.PurgeTime,
|
||||
"reality_device_number": disk.RealityDeviceNumber,
|
||||
"reference_id": disk.ReferenceId,
|
||||
"res_id": disk.ResID,
|
||||
"res_name": disk.ResName,
|
||||
"role": disk.Role,
|
||||
"sep_id": disk.SepID,
|
||||
"sep_type": disk.SepType,
|
||||
"size_max": disk.SizeMax,
|
||||
"size_used": disk.SizeUsed,
|
||||
"snapshots": flattendDiskSnapshotList(disk.Snapshots),
|
||||
"status": disk.Status,
|
||||
"tech_status": disk.TechStatus,
|
||||
"type": disk.Type,
|
||||
"vmid": disk.VMID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func flattendDiskSnapshotList(sl SnapshotList) []interface{} {
|
||||
res := make([]interface{}, 0)
|
||||
for _, snapshot := range sl {
|
||||
temp := map[string]interface{}{
|
||||
"guid": snapshot.Guid,
|
||||
"label": snapshot.Label,
|
||||
"res_id": snapshot.ResId,
|
||||
"snap_set_guid": snapshot.SnapSetGuid,
|
||||
"snap_set_time": snapshot.SnapSetTime,
|
||||
"timestamp": snapshot.TimeStamp,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func dataSourceDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
diskList, err := utilityDiskListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -195,14 +96,6 @@ func dataSourceDiskListSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
|
||||
153
internal/service/cloudbroker/disks/flattens.go
Normal file
153
internal/service/cloudbroker/disks/flattens.go
Normal file
@@ -0,0 +1,153 @@
|
||||
package disks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks"
|
||||
)
|
||||
|
||||
func flattenDisk(d *schema.ResourceData, disk *disks.RecordDisk) {
|
||||
diskAcl, _ := json.Marshal(disk.ACL)
|
||||
|
||||
d.Set("account_id", disk.AccountID)
|
||||
d.Set("account_name", disk.AccountName)
|
||||
d.Set("acl", string(diskAcl))
|
||||
d.Set("boot_partition", disk.BootPartition)
|
||||
d.Set("created_time", disk.CreatedTime)
|
||||
d.Set("deleted_time", disk.DeletedTime)
|
||||
d.Set("desc", disk.Description)
|
||||
d.Set("destruction_time", disk.DestructionTime)
|
||||
d.Set("devicename", disk.DeviceName)
|
||||
d.Set("disk_path", disk.DiskPath)
|
||||
d.Set("gid", disk.GID)
|
||||
d.Set("guid", disk.GUID)
|
||||
d.Set("disk_id", disk.ID)
|
||||
d.Set("image_id", disk.ImageID)
|
||||
d.Set("images", disk.Images)
|
||||
d.Set("iotune", flattenIOTune(disk.IOTune))
|
||||
d.Set("iqn", disk.IQN)
|
||||
d.Set("login", disk.Login)
|
||||
d.Set("milestones", disk.Milestones)
|
||||
d.Set("disk_name", disk.Name)
|
||||
d.Set("order", disk.Order)
|
||||
d.Set("params", disk.Params)
|
||||
d.Set("parent_id", disk.ParentID)
|
||||
d.Set("passwd", disk.Password)
|
||||
d.Set("pci_slot", disk.PCISlot)
|
||||
d.Set("pool", disk.Pool)
|
||||
d.Set("purge_attempts", disk.PurgeAttempts)
|
||||
d.Set("purge_time", disk.PurgeTime)
|
||||
d.Set("reality_device_number", disk.RealityDeviceNumber)
|
||||
d.Set("reference_id", disk.ReferenceID)
|
||||
d.Set("res_id", disk.ResID)
|
||||
d.Set("res_name", disk.ResName)
|
||||
d.Set("role", disk.Role)
|
||||
d.Set("sep_id", disk.SEPID)
|
||||
d.Set("sep_type", disk.SEPType)
|
||||
d.Set("size_max", disk.SizeMax)
|
||||
d.Set("size_used", disk.SizeUsed)
|
||||
d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots))
|
||||
d.Set("status", disk.Status)
|
||||
d.Set("tech_status", disk.TechStatus)
|
||||
d.Set("type", disk.Type)
|
||||
d.Set("vmid", disk.VMID)
|
||||
}
|
||||
|
||||
func flattenIOTune(iot disks.IOTune) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"read_bytes_sec": iot.ReadBytesSec,
|
||||
"read_bytes_sec_max": iot.ReadBytesSecMax,
|
||||
"read_iops_sec": iot.ReadIOPSSec,
|
||||
"read_iops_sec_max": iot.ReadIOPSSecMax,
|
||||
"size_iops_sec": iot.SizeIOPSSec,
|
||||
"total_bytes_sec": iot.TotalBytesSec,
|
||||
"total_bytes_sec_max": iot.TotalBytesSecMax,
|
||||
"total_iops_sec": iot.TotalIOPSSec,
|
||||
"total_iops_sec_max": iot.TotalIOPSSecMax,
|
||||
"write_bytes_sec": iot.WriteBytesSec,
|
||||
"write_bytes_sec_max": iot.WriteBytesSecMax,
|
||||
"write_iops_sec": iot.WriteIOPSSec,
|
||||
"write_iops_sec_max": iot.WriteIOPSSecMax,
|
||||
}
|
||||
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenDiskList(dl disks.ListDisks) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, disk := range dl {
|
||||
diskAcl, _ := json.Marshal(disk.ACL)
|
||||
temp := map[string]interface{}{
|
||||
"account_id": disk.AccountID,
|
||||
"account_name": disk.AccountName,
|
||||
"acl": string(diskAcl),
|
||||
"boot_partition": disk.BootPartition,
|
||||
// "compute_id": disk.MachineID,
|
||||
// "compute_name": disk.MachineName,
|
||||
"created_time": disk.CreatedTime,
|
||||
"deleted_time": disk.DeletedTime,
|
||||
"desc": disk.Description,
|
||||
"destruction_time": disk.DestructionTime,
|
||||
"devicename": disk.DeviceName,
|
||||
"disk_path": disk.DiskPath,
|
||||
"gid": disk.GID,
|
||||
"guid": disk.GUID,
|
||||
"disk_id": disk.ID,
|
||||
"image_id": disk.ImageID,
|
||||
"images": disk.Images,
|
||||
"iotune": flattenIOTune(disk.IOTune),
|
||||
"iqn": disk.IQN,
|
||||
"login": disk.Login,
|
||||
"machine_id": disk.MachineID,
|
||||
"machine_name": disk.MachineName,
|
||||
"milestones": disk.Milestones,
|
||||
"disk_name": disk.Name,
|
||||
"order": disk.Order,
|
||||
"params": disk.Params,
|
||||
"parent_id": disk.ParentID,
|
||||
"passwd": disk.Password,
|
||||
"pci_slot": disk.PCISlot,
|
||||
"pool": disk.Pool,
|
||||
"purge_attempts": disk.PurgeAttempts,
|
||||
"purge_time": disk.PurgeTime,
|
||||
"reality_device_number": disk.RealityDeviceNumber,
|
||||
"reference_id": disk.ReferenceID,
|
||||
"res_id": disk.ResID,
|
||||
"res_name": disk.ResName,
|
||||
"role": disk.Role,
|
||||
"sep_id": disk.SEPID,
|
||||
"sep_type": disk.SEPType,
|
||||
"size_max": disk.SizeMax,
|
||||
"size_used": disk.SizeUsed,
|
||||
"snapshots": flattendDiskSnapshotList(disk.Snapshots),
|
||||
"status": disk.Status,
|
||||
"tech_status": disk.TechStatus,
|
||||
"type": disk.Type,
|
||||
"vmid": disk.VMID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func flattendDiskSnapshotList(sl disks.ListSnapshots) []interface{} {
|
||||
res := make([]interface{}, 0)
|
||||
for _, snapshot := range sl {
|
||||
temp := map[string]interface{}{
|
||||
"guid": snapshot.GUID,
|
||||
"label": snapshot.Label,
|
||||
"res_id": snapshot.ResID,
|
||||
"snap_set_guid": snapshot.SnapSetGUID,
|
||||
"snap_set_time": snapshot.SnapSetTime,
|
||||
"timestamp": snapshot.Timestamp,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
return res
|
||||
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package disks
|
||||
|
||||
type Disk struct {
|
||||
Acl map[string]interface{} `json:"acl"`
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
BootPartition int `json:"bootPartition"`
|
||||
CreatedTime uint64 `json:"creationTime"`
|
||||
ComputeID int `json:"computeId"`
|
||||
ComputeName string `json:"computeName"`
|
||||
DeletedTime uint64 `json:"deletionTime"`
|
||||
DeviceName string `json:"devicename"`
|
||||
Desc string `json:"desc"`
|
||||
DestructionTime uint64 `json:"destructionTime"`
|
||||
DiskPath string `json:"diskPath"`
|
||||
GridID int `json:"gid"`
|
||||
GUID int `json:"guid"`
|
||||
ID uint `json:"id"`
|
||||
ImageID int `json:"imageId"`
|
||||
Images []int `json:"images"`
|
||||
IOTune IOTune `json:"iotune"`
|
||||
IQN string `json:"iqn"`
|
||||
Login string `json:"login"`
|
||||
Name string `json:"name"`
|
||||
MachineId int `json:"machineId"`
|
||||
MachineName string `json:"machineName"`
|
||||
Milestones uint64 `json:"milestones"`
|
||||
Order int `json:"order"`
|
||||
Params string `json:"params"`
|
||||
Passwd string `json:"passwd"`
|
||||
ParentId int `json:"parentId"`
|
||||
PciSlot int `json:"pciSlot"`
|
||||
Pool string `json:"pool"`
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
PurgeAttempts uint64 `json:"purgeAttempts"`
|
||||
RealityDeviceNumber int `json:"realityDeviceNumber"`
|
||||
ReferenceId string `json:"referenceId"`
|
||||
ResID string `json:"resId"`
|
||||
ResName string `json:"resName"`
|
||||
Role string `json:"role"`
|
||||
SepType string `json:"sepType"`
|
||||
SepID int `json:"sepId"` // NOTE: absent from compute/get output
|
||||
SizeMax int `json:"sizeMax"`
|
||||
SizeUsed float64 `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space
|
||||
Snapshots []Snapshot `json:"snapshots"`
|
||||
Status string `json:"status"`
|
||||
TechStatus string `json:"techStatus"`
|
||||
Type string `json:"type"`
|
||||
UpdateBy uint64 `json:"updateBy"`
|
||||
VMID int `json:"vmid"`
|
||||
}
|
||||
|
||||
type Snapshot struct {
|
||||
Guid string `json:"guid"`
|
||||
Label string `json:"label"`
|
||||
ResId string `json:"resId"`
|
||||
SnapSetGuid string `json:"snapSetGuid"`
|
||||
SnapSetTime uint64 `json:"snapSetTime"`
|
||||
TimeStamp uint64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type SnapshotList []Snapshot
|
||||
|
||||
type DisksList []Disk
|
||||
|
||||
type IOTune struct {
|
||||
ReadBytesSec int `json:"read_bytes_sec"`
|
||||
ReadBytesSecMax int `json:"read_bytes_sec_max"`
|
||||
ReadIopsSec int `json:"read_iops_sec"`
|
||||
ReadIopsSecMax int `json:"read_iops_sec_max"`
|
||||
SizeIopsSec int `json:"size_iops_sec"`
|
||||
TotalBytesSec int `json:"total_bytes_sec"`
|
||||
TotalBytesSecMax int `json:"total_bytes_sec_max"`
|
||||
TotalIopsSec int `json:"total_iops_sec"`
|
||||
TotalIopsSecMax int `json:"total_iops_sec_max"`
|
||||
WriteBytesSec int `json:"write_bytes_sec"`
|
||||
WriteBytesSecMax int `json:"write_bytes_sec_max"`
|
||||
WriteIopsSec int `json:"write_iops_sec"`
|
||||
WriteIopsSecMax int `json:"write_iops_sec_max"`
|
||||
}
|
||||
@@ -33,15 +33,14 @@ package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -50,230 +49,178 @@ import (
|
||||
|
||||
func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := disks.CreateRequest{}
|
||||
|
||||
req.AccountID = uint64(d.Get("account_id").(int))
|
||||
req.GID = uint64(d.Get("gid").(int))
|
||||
req.Name = d.Get("disk_name").(string)
|
||||
req.Size = uint64(d.Get("size_max").(int))
|
||||
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
||||
urlValues.Add("gid", fmt.Sprintf("%d", d.Get("gid").(int)))
|
||||
urlValues.Add("name", d.Get("disk_name").(string))
|
||||
urlValues.Add("size", fmt.Sprintf("%d", d.Get("size_max").(int)))
|
||||
if typeRaw, ok := d.GetOk("type"); ok {
|
||||
urlValues.Add("type", strings.ToUpper(typeRaw.(string)))
|
||||
req.Type = strings.ToUpper(typeRaw.(string))
|
||||
} else {
|
||||
urlValues.Add("type", "D")
|
||||
req.Type = "D"
|
||||
}
|
||||
|
||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||
urlValues.Add("sep_id", strconv.Itoa(sepId.(int)))
|
||||
req.SEPID = uint64(sepId.(int))
|
||||
}
|
||||
|
||||
if poolName, ok := d.GetOk("pool"); ok {
|
||||
urlValues.Add("pool", poolName.(string))
|
||||
req.Pool = poolName.(string)
|
||||
}
|
||||
|
||||
argVal, argSet := d.GetOk("desc")
|
||||
if argSet {
|
||||
urlValues.Add("description", argVal.(string))
|
||||
req.Description = argVal.(string)
|
||||
}
|
||||
|
||||
diskId, err := c.DecortAPICall(ctx, "POST", disksCreateAPI, urlValues)
|
||||
diskId, err := c.CloudBroker().Disks().Create(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
|
||||
d.SetId(diskId) // update ID of the resource to tell Terraform that the disk resource exists
|
||||
d.SetId(strconv.FormatUint(diskId, 10))
|
||||
|
||||
if iotuneRaw, ok := d.GetOk("iotune"); ok {
|
||||
iot := iotuneRaw.([]interface{})[0]
|
||||
iotune := iot.(map[string]interface{})
|
||||
urlValues.Add("diskId", diskId)
|
||||
urlValues.Add("iops", strconv.Itoa(iotune["total_iops_sec"].(int)))
|
||||
urlValues.Add("read_bytes_sec", strconv.Itoa(iotune["read_bytes_sec"].(int)))
|
||||
urlValues.Add("read_bytes_sec_max", strconv.Itoa(iotune["read_bytes_sec_max"].(int)))
|
||||
urlValues.Add("read_iops_sec", strconv.Itoa(iotune["read_iops_sec"].(int)))
|
||||
urlValues.Add("read_iops_sec_max", strconv.Itoa(iotune["read_iops_sec_max"].(int)))
|
||||
urlValues.Add("size_iops_sec", strconv.Itoa(iotune["size_iops_sec"].(int)))
|
||||
urlValues.Add("total_bytes_sec", strconv.Itoa(iotune["total_bytes_sec"].(int)))
|
||||
urlValues.Add("total_bytes_sec_max", strconv.Itoa(iotune["total_bytes_sec_max"].(int)))
|
||||
urlValues.Add("total_iops_sec_max", strconv.Itoa(iotune["total_iops_sec_max"].(int)))
|
||||
urlValues.Add("write_bytes_sec", strconv.Itoa(iotune["write_bytes_sec"].(int)))
|
||||
urlValues.Add("write_bytes_sec_max", strconv.Itoa(iotune["write_bytes_sec_max"].(int)))
|
||||
urlValues.Add("write_iops_sec", strconv.Itoa(iotune["write_iops_sec"].(int)))
|
||||
urlValues.Add("write_iops_sec_max", strconv.Itoa(iotune["write_iops_sec_max"].(int)))
|
||||
req := disks.LimitIORequest{
|
||||
DiskID: diskId,
|
||||
IOPS: uint64(iotune["total_iops_sec"].(int)),
|
||||
TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)),
|
||||
ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)),
|
||||
WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)),
|
||||
TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)),
|
||||
ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)),
|
||||
WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)),
|
||||
TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)),
|
||||
ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)),
|
||||
WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)),
|
||||
TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)),
|
||||
ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)),
|
||||
WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)),
|
||||
SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", disksIOLimitAPI, urlValues)
|
||||
_, err := c.CloudBroker().Disks().LimitIO(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
dgn := resourceDiskRead(ctx, d, m)
|
||||
if dgn != nil {
|
||||
return dgn
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourceDiskRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
disk, err := utilityDiskCheckPresence(ctx, d, m)
|
||||
if disk == nil {
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
diskAcl, _ := json.Marshal(disk.Acl)
|
||||
|
||||
d.Set("account_id", disk.AccountID)
|
||||
d.Set("account_name", disk.AccountName)
|
||||
d.Set("acl", string(diskAcl))
|
||||
d.Set("boot_partition", disk.BootPartition)
|
||||
d.Set("compute_id", disk.ComputeID)
|
||||
d.Set("compute_name", disk.ComputeName)
|
||||
d.Set("created_time", disk.CreatedTime)
|
||||
d.Set("deleted_time", disk.DeletedTime)
|
||||
d.Set("desc", disk.Desc)
|
||||
d.Set("destruction_time", disk.DestructionTime)
|
||||
d.Set("devicename", disk.DeviceName)
|
||||
d.Set("disk_path", disk.DiskPath)
|
||||
d.Set("gid", disk.GridID)
|
||||
d.Set("guid", disk.GUID)
|
||||
d.Set("disk_id", disk.ID)
|
||||
d.Set("image_id", disk.ImageID)
|
||||
d.Set("images", disk.Images)
|
||||
d.Set("iotune", flattenIOTune(disk.IOTune))
|
||||
d.Set("iqn", disk.IQN)
|
||||
d.Set("login", disk.Login)
|
||||
d.Set("milestones", disk.Milestones)
|
||||
d.Set("disk_name", disk.Name)
|
||||
d.Set("order", disk.Order)
|
||||
d.Set("params", disk.Params)
|
||||
d.Set("parent_id", disk.ParentId)
|
||||
d.Set("passwd", disk.Passwd)
|
||||
d.Set("pci_slot", disk.PciSlot)
|
||||
d.Set("pool", disk.Pool)
|
||||
d.Set("purge_attempts", disk.PurgeAttempts)
|
||||
d.Set("purge_time", disk.PurgeTime)
|
||||
d.Set("reality_device_number", disk.RealityDeviceNumber)
|
||||
d.Set("reference_id", disk.ReferenceId)
|
||||
d.Set("res_id", disk.ResID)
|
||||
d.Set("res_name", disk.ResName)
|
||||
d.Set("role", disk.Role)
|
||||
d.Set("sep_id", disk.SepID)
|
||||
d.Set("sep_type", disk.SepType)
|
||||
d.Set("size_max", disk.SizeMax)
|
||||
d.Set("size_used", disk.SizeUsed)
|
||||
d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots))
|
||||
d.Set("status", disk.Status)
|
||||
d.Set("tech_status", disk.TechStatus)
|
||||
d.Set("type", disk.Type)
|
||||
d.Set("vmid", disk.VMID)
|
||||
flattenDisk(d, disk)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
diskID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
if d.HasChange("size_max") {
|
||||
oldSize, newSize := d.GetChange("size_max")
|
||||
if oldSize.(int) < newSize.(int) {
|
||||
log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB",
|
||||
d.Id(), oldSize.(int), newSize.(int))
|
||||
urlValues.Add("diskId", d.Id())
|
||||
urlValues.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", disksResizeAPI, urlValues)
|
||||
req := disks.ResizeRequest{
|
||||
DiskID: diskID,
|
||||
Size: uint64(newSize.(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Disks().Resize(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("size_max", newSize)
|
||||
} else if oldSize.(int) > newSize.(int) {
|
||||
return diag.FromErr(fmt.Errorf("resourceDiskUpdate: Disk ID %s - reducing disk size is not allowed", d.Id()))
|
||||
}
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("disk_name") {
|
||||
urlValues.Add("diskId", d.Id())
|
||||
urlValues.Add("name", d.Get("disk_name").(string))
|
||||
_, err := c.DecortAPICall(ctx, "POST", disksRenameAPI, urlValues)
|
||||
req := disks.RenameRequest{
|
||||
DiskID: diskID,
|
||||
Name: d.Get("disk_name").(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Disks().Rename(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("iotune") {
|
||||
iot := d.Get("iotune").([]interface{})[0]
|
||||
iotune := iot.(map[string]interface{})
|
||||
urlValues.Add("diskId", d.Id())
|
||||
urlValues.Add("iops", strconv.Itoa(iotune["total_iops_sec"].(int)))
|
||||
urlValues.Add("read_bytes_sec", strconv.Itoa(iotune["read_bytes_sec"].(int)))
|
||||
urlValues.Add("read_bytes_sec_max", strconv.Itoa(iotune["read_bytes_sec_max"].(int)))
|
||||
urlValues.Add("read_iops_sec", strconv.Itoa(iotune["read_iops_sec"].(int)))
|
||||
urlValues.Add("read_iops_sec_max", strconv.Itoa(iotune["read_iops_sec_max"].(int)))
|
||||
urlValues.Add("size_iops_sec", strconv.Itoa(iotune["size_iops_sec"].(int)))
|
||||
urlValues.Add("total_bytes_sec", strconv.Itoa(iotune["total_bytes_sec"].(int)))
|
||||
urlValues.Add("total_bytes_sec_max", strconv.Itoa(iotune["total_bytes_sec_max"].(int)))
|
||||
urlValues.Add("total_iops_sec_max", strconv.Itoa(iotune["total_iops_sec_max"].(int)))
|
||||
urlValues.Add("write_bytes_sec", strconv.Itoa(iotune["write_bytes_sec"].(int)))
|
||||
urlValues.Add("write_bytes_sec_max", strconv.Itoa(iotune["write_bytes_sec_max"].(int)))
|
||||
urlValues.Add("write_iops_sec", strconv.Itoa(iotune["write_iops_sec"].(int)))
|
||||
urlValues.Add("write_iops_sec_max", strconv.Itoa(iotune["write_iops_sec_max"].(int)))
|
||||
req := disks.LimitIORequest{
|
||||
DiskID: diskID,
|
||||
IOPS: uint64(iotune["total_iops_sec"].(int)),
|
||||
TotalBytesSec: uint64(iotune["total_bytes_sec"].(int)),
|
||||
ReadBytesSec: uint64(iotune["read_bytes_sec"].(int)),
|
||||
WriteBytesSec: uint64(iotune["write_bytes_sec"].(int)),
|
||||
TotalIOPSSec: uint64(iotune["total_iops_sec"].(int)),
|
||||
ReadIOPSSec: uint64(iotune["read_iops_sec"].(int)),
|
||||
WriteIOPSSec: uint64(iotune["write_iops_sec"].(int)),
|
||||
TotalBytesSecMax: uint64(iotune["total_bytes_sec_max"].(int)),
|
||||
ReadBytesSecMax: uint64(iotune["read_bytes_sec_max"].(int)),
|
||||
WriteBytesSecMax: uint64(iotune["write_bytes_sec_max"].(int)),
|
||||
TotalIOPSSecMax: uint64(iotune["total_iops_sec_max"].(int)),
|
||||
ReadIOPSSecMax: uint64(iotune["read_iops_sec_max"].(int)),
|
||||
WriteIOPSSecMax: uint64(iotune["write_iops_sec_max"].(int)),
|
||||
SizeIOPSSec: uint64(iotune["size_iops_sec"].(int)),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", disksIOLimitAPI, urlValues)
|
||||
_, err := c.CloudBroker().Disks().LimitIO(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("restore") {
|
||||
if d.Get("restore").(bool) {
|
||||
urlValues.Add("diskId", d.Id())
|
||||
urlValues.Add("reason", d.Get("reason").(string))
|
||||
req := disks.RestoreRequest{
|
||||
DiskID: diskID,
|
||||
Reason: d.Get("reason").(string),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues)
|
||||
_, err := c.CloudBroker().Disks().Restore(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return resourceDiskRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
disk, err := utilityDiskCheckPresence(ctx, d, m)
|
||||
if disk == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
params := &url.Values{}
|
||||
params.Add("diskId", d.Id())
|
||||
params.Add("detach", strconv.FormatBool(d.Get("detach").(bool)))
|
||||
params.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
|
||||
params.Add("reason", d.Get("reason").(string))
|
||||
req := disks.DeleteRequest{
|
||||
DiskID: disk.ID,
|
||||
Detach: d.Get("detach").(bool),
|
||||
Permanently: d.Get("permanently").(bool),
|
||||
Reason: d.Get("reason").(string),
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
_, err = c.DecortAPICall(ctx, "POST", disksDeleteAPI, params)
|
||||
_, err = c.CloudBroker().Disks().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -362,14 +309,6 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
|
||||
@@ -33,35 +33,28 @@ package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Disk, error) {
|
||||
func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*disks.RecordDisk, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
disk := &Disk{}
|
||||
req := disks.GetRequest{}
|
||||
|
||||
if d.Get("disk_id").(int) == 0 {
|
||||
urlValues.Add("diskId", d.Id())
|
||||
id, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req.DiskID = id
|
||||
} else {
|
||||
urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int)))
|
||||
req.DiskID = uint64(d.Get("disk_id").(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityDiskCheckPresence: load disk")
|
||||
diskRaw, err := c.DecortAPICall(ctx, "POST", disksGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(diskRaw), disk)
|
||||
disk, err := c.CloudBroker().Disks().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,42 +33,34 @@ package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (DisksList, error) {
|
||||
diskList := DisksList{}
|
||||
func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (disks.ListDisks, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := disks.ListRequest{}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
if diskType, ok := d.GetOk("type"); ok {
|
||||
urlValues.Add("type", strings.ToUpper(diskType.(string)))
|
||||
req.Type = strings.ToUpper(diskType.(string))
|
||||
}
|
||||
if accountId, ok := d.GetOk("accountId"); ok {
|
||||
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
||||
req.AccountID = uint64(accountId.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityDiskListCheckPresence: load disk list")
|
||||
diskListRaw, err := c.DecortAPICall(ctx, "POST", disksListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(diskListRaw), &diskList)
|
||||
diskList, err := c.CloudBroker().Disks().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -40,21 +40,12 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenGrid(d *schema.ResourceData, grid *Grid) {
|
||||
d.Set("name", grid.Name)
|
||||
d.Set("flag", grid.Flag)
|
||||
d.Set("gid", grid.Gid)
|
||||
d.Set("guid", grid.Guid)
|
||||
d.Set("location_code", grid.LocationCode)
|
||||
d.Set("id", grid.Id)
|
||||
}
|
||||
|
||||
func dataSourceGridRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
grid, err := utilityGridCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
d.SetId(strconv.Itoa(grid.Id))
|
||||
d.SetId(strconv.FormatUint(grid.ID, 10))
|
||||
flattenGrid(d, grid)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -40,23 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenGridList(gl GridList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range gl {
|
||||
temp := map[string]interface{}{
|
||||
"name": item.Name,
|
||||
"flag": item.Flag,
|
||||
"gid": item.Gid,
|
||||
"guid": item.Guid,
|
||||
"location_code": item.LocationCode,
|
||||
"id": item.Id,
|
||||
}
|
||||
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func dataSourceGridListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
gridList, err := utilityGridListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
32
internal/service/cloudbroker/grid/flattens.go
Normal file
32
internal/service/cloudbroker/grid/flattens.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package grid
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid"
|
||||
)
|
||||
|
||||
func flattenGrid(d *schema.ResourceData, grid *grid.RecordGrid) {
|
||||
d.Set("name", grid.Name)
|
||||
d.Set("flag", grid.Flag)
|
||||
d.Set("gid", grid.GID)
|
||||
d.Set("guid", grid.GUID)
|
||||
d.Set("location_code", grid.LocationCode)
|
||||
d.Set("id", grid.ID)
|
||||
}
|
||||
|
||||
func flattenGridList(gl grid.ListGrids) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range gl {
|
||||
temp := map[string]interface{}{
|
||||
"name": item.Name,
|
||||
"flag": item.Flag,
|
||||
"gid": item.GID,
|
||||
"guid": item.GUID,
|
||||
"location_code": item.LocationCode,
|
||||
"id": item.ID,
|
||||
}
|
||||
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package grid
|
||||
|
||||
type Grid struct {
|
||||
Flag string `json:"flag"`
|
||||
Gid int `json:"gid"`
|
||||
Guid int `json:"guid"`
|
||||
Id int `json:"id"`
|
||||
LocationCode string `json:"locationCode"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type GridList []Grid
|
||||
@@ -33,35 +33,27 @@ package grid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityGridCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Grid, error) {
|
||||
grid := &Grid{}
|
||||
func utilityGridCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*grid.RecordGrid, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := grid.GetRequest{}
|
||||
|
||||
if gridId, ok := d.GetOk("grid_id"); ok {
|
||||
urlValues.Add("gridId", strconv.Itoa(gridId.(int)))
|
||||
req.GID = uint64(gridId.(int))
|
||||
} else {
|
||||
return nil, errors.New("grid_id is required")
|
||||
}
|
||||
|
||||
log.Debugf("utilityGridCheckPresence: load grid")
|
||||
gridRaw, err := c.DecortAPICall(ctx, "POST", GridGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(gridRaw), grid)
|
||||
grid, err := c.CloudBroker().Grid().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,35 +33,27 @@ package grid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityGridListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (GridList, error) {
|
||||
gridList := GridList{}
|
||||
func utilityGridListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (grid.ListGrids, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := grid.ListRequest{}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityGridListCheckPresence: load grid list")
|
||||
gridListRaw, err := c.DecortAPICall(ctx, "POST", GridListGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(gridListRaw), &gridList)
|
||||
gridList, err := c.CloudBroker().Grid().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -38,57 +38,15 @@ import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
)
|
||||
|
||||
func flattenImage(d *schema.ResourceData, image *Image) {
|
||||
d.Set("name", image.Name)
|
||||
d.Set("drivers", image.Drivers)
|
||||
d.Set("url", image.Url)
|
||||
d.Set("gid", image.Gid)
|
||||
d.Set("image_id", image.ImageId)
|
||||
d.Set("boot_type", image.Boottype)
|
||||
d.Set("image_type", image.Imagetype)
|
||||
d.Set("bootable", image.Bootable)
|
||||
d.Set("sep_id", image.SepId)
|
||||
d.Set("unc_path", image.UNCPath)
|
||||
d.Set("link_to", image.LinkTo)
|
||||
d.Set("status", image.Status)
|
||||
d.Set("tech_status", image.TechStatus)
|
||||
d.Set("version", image.Version)
|
||||
d.Set("size", image.Size)
|
||||
d.Set("enabled", image.Enabled)
|
||||
d.Set("computeci_id", image.ComputeciId)
|
||||
d.Set("pool_name", image.PoolName)
|
||||
d.Set("username", image.Username)
|
||||
d.Set("username_dl", image.UsernameDL)
|
||||
d.Set("password", image.Password)
|
||||
d.Set("password_dl", image.PasswordDL)
|
||||
d.Set("account_id", image.AccountId)
|
||||
d.Set("guid", image.Guid)
|
||||
d.Set("milestones", image.Milestones)
|
||||
d.Set("provider_name", image.ProviderName)
|
||||
d.Set("purge_attempts", image.PurgeAttempts)
|
||||
d.Set("reference_id", image.ReferenceId)
|
||||
d.Set("res_id", image.ResId)
|
||||
d.Set("res_name", image.ResName)
|
||||
d.Set("rescuecd", image.Rescuecd)
|
||||
d.Set("architecture", image.Architecture)
|
||||
d.Set("hot_resize", image.Hotresize)
|
||||
d.Set("history", flattenHistory(image.History))
|
||||
d.Set("last_modified", image.LastModified)
|
||||
d.Set("meta", flattens.FlattenMeta(image.Meta))
|
||||
d.Set("desc", image.Desc)
|
||||
d.Set("shared_with", image.SharedWith)
|
||||
}
|
||||
|
||||
func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
d.SetId(strconv.Itoa(image.Guid))
|
||||
d.SetId(strconv.FormatUint(image.ID, 10))
|
||||
flattenImage(d, image)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -40,54 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenImageList(il ImageList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range il {
|
||||
temp := map[string]interface{}{
|
||||
"name": item.Name,
|
||||
"url": item.Url,
|
||||
"gid": item.Gid,
|
||||
"guid": item.Guid,
|
||||
"drivers": item.Drivers,
|
||||
"image_id": item.ImageId,
|
||||
"boot_type": item.Boottype,
|
||||
"bootable": item.Bootable,
|
||||
"image_type": item.Imagetype,
|
||||
"status": item.Status,
|
||||
"tech_status": item.TechStatus,
|
||||
"version": item.Version,
|
||||
"username": item.Username,
|
||||
"username_dl": item.UsernameDL,
|
||||
"password": item.Password,
|
||||
"password_dl": item.PasswordDL,
|
||||
"purge_attempts": item.PurgeAttempts,
|
||||
"architecture": item.Architecture,
|
||||
"account_id": item.AccountId,
|
||||
"computeci_id": item.ComputeciId,
|
||||
"enabled": item.Enabled,
|
||||
"reference_id": item.ReferenceId,
|
||||
"res_id": item.ResId,
|
||||
"res_name": item.ResName,
|
||||
"rescuecd": item.Rescuecd,
|
||||
"provider_name": item.ProviderName,
|
||||
"milestones": item.Milestones,
|
||||
"size": item.Size,
|
||||
"sep_id": item.SepId,
|
||||
"link_to": item.LinkTo,
|
||||
"unc_path": item.UNCPath,
|
||||
"pool_name": item.PoolName,
|
||||
"hot_resize": item.Hotresize,
|
||||
"history": flattenHistory(item.History),
|
||||
"last_modified": item.LastModified,
|
||||
"meta": flattenMeta(item.Meta),
|
||||
"desc": item.Desc,
|
||||
"shared_with": item.SharedWith,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
imageList, err := utilityImageListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
@@ -40,32 +40,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenImageListStacks(_ *schema.ResourceData, stack ImageListStacks) []map[string]interface{} {
|
||||
temp := make([]map[string]interface{}, 0)
|
||||
for _, item := range stack {
|
||||
t := map[string]interface{}{
|
||||
"api_url": item.ApiURL,
|
||||
"api_key": item.ApiKey,
|
||||
"app_id": item.AppId,
|
||||
"desc": item.Desc,
|
||||
"drivers": item.Drivers,
|
||||
"error": item.Error,
|
||||
"guid": item.Guid,
|
||||
"id": item.Id,
|
||||
"images": item.Images,
|
||||
"login": item.Login,
|
||||
"name": item.Name,
|
||||
"passwd": item.Passwd,
|
||||
"reference_id": item.ReferenceId,
|
||||
"status": item.Status,
|
||||
"type": item.Type,
|
||||
}
|
||||
|
||||
temp = append(temp, t)
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
func dataSourceImageListStacksRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
imageListStacks, err := utilityImageListStacksCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
157
internal/service/cloudbroker/image/flattens.go
Normal file
157
internal/service/cloudbroker/image/flattens.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
)
|
||||
|
||||
func flattenImage(d *schema.ResourceData, img *image.RecordImage) {
|
||||
d.Set("name", img.Name)
|
||||
d.Set("drivers", img.Drivers)
|
||||
d.Set("url", img.URL)
|
||||
d.Set("gid", img.GID)
|
||||
d.Set("image_id", img.ID)
|
||||
d.Set("boot_type", img.BootType)
|
||||
d.Set("image_type", img.Type)
|
||||
d.Set("bootable", img.Bootable)
|
||||
d.Set("sep_id", img.SEPID)
|
||||
d.Set("unc_path", img.UNCPath)
|
||||
d.Set("link_to", img.LinkTo)
|
||||
d.Set("status", img.Status)
|
||||
d.Set("tech_status", img.TechStatus)
|
||||
d.Set("version", img.Version)
|
||||
d.Set("size", img.Size)
|
||||
d.Set("enabled", img.Enabled)
|
||||
d.Set("computeci_id", img.ComputeCIID)
|
||||
d.Set("pool_name", img.Pool)
|
||||
d.Set("username", img.Username)
|
||||
// d.Set("username_dl", img.UsernameDL)
|
||||
d.Set("password", img.Password)
|
||||
// d.Set("password_dl", img.PasswordDL)
|
||||
d.Set("account_id", img.AccountID)
|
||||
d.Set("guid", img.GUID)
|
||||
d.Set("milestones", img.Milestones)
|
||||
d.Set("provider_name", img.ProviderName)
|
||||
d.Set("purge_attempts", img.PurgeAttempts)
|
||||
d.Set("reference_id", img.ReferenceID)
|
||||
d.Set("res_id", img.ResID)
|
||||
d.Set("res_name", img.ResName)
|
||||
d.Set("rescuecd", img.RescueCD)
|
||||
d.Set("architecture", img.Architecture)
|
||||
d.Set("hot_resize", img.HotResize)
|
||||
d.Set("history", flattenHistory(img.History))
|
||||
d.Set("last_modified", img.LastModified)
|
||||
d.Set("meta", flattens.FlattenMeta(img.Meta))
|
||||
d.Set("desc", img.Description)
|
||||
d.Set("shared_with", img.SharedWith)
|
||||
}
|
||||
|
||||
func flattenMeta(m []interface{}) []string {
|
||||
output := []string{}
|
||||
for _, item := range m {
|
||||
switch d := item.(type) {
|
||||
case string:
|
||||
output = append(output, d)
|
||||
case int:
|
||||
output = append(output, strconv.Itoa(d))
|
||||
case int64:
|
||||
output = append(output, strconv.FormatInt(d, 10))
|
||||
case float64:
|
||||
output = append(output, strconv.FormatInt(int64(d), 10))
|
||||
default:
|
||||
output = append(output, "")
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func flattenHistory(history []image.History) []map[string]interface{} {
|
||||
temp := make([]map[string]interface{}, 0)
|
||||
for _, item := range history {
|
||||
t := map[string]interface{}{
|
||||
"id": item.ID,
|
||||
"guid": item.GUID,
|
||||
"timestamp": item.Timestamp,
|
||||
}
|
||||
|
||||
temp = append(temp, t)
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
func flattenImageList(il image.ListImages) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range il {
|
||||
temp := map[string]interface{}{
|
||||
"name": item.Name,
|
||||
"url": item.URL,
|
||||
"gid": item.GID,
|
||||
"guid": item.GUID,
|
||||
"drivers": item.Drivers,
|
||||
"image_id": item.ID,
|
||||
"boot_type": item.BootType,
|
||||
"bootable": item.Bootable,
|
||||
"image_type": item.Type,
|
||||
"status": item.Status,
|
||||
"tech_status": item.TechStatus,
|
||||
"version": item.Version,
|
||||
"username": item.Username,
|
||||
// "username_dl": item.UsernameDL,
|
||||
"password": item.Password,
|
||||
// "password_dl": item.PasswordDL,
|
||||
"purge_attempts": item.PurgeAttempts,
|
||||
"architecture": item.Architecture,
|
||||
"account_id": item.AccountID,
|
||||
"computeci_id": item.ComputeCIID,
|
||||
"enabled": item.Enabled,
|
||||
"reference_id": item.ReferenceID,
|
||||
"res_id": item.ResID,
|
||||
"res_name": item.ResName,
|
||||
"rescuecd": item.RescueCD,
|
||||
"provider_name": item.ProviderName,
|
||||
"milestones": item.Milestones,
|
||||
"size": item.Size,
|
||||
"sep_id": item.SEPID,
|
||||
"link_to": item.LinkTo,
|
||||
"unc_path": item.UNCPath,
|
||||
"pool_name": item.Pool,
|
||||
"hot_resize": item.HotResize,
|
||||
"history": flattenHistory(item.History),
|
||||
"last_modified": item.LastModified,
|
||||
"meta": flattenMeta(item.Meta),
|
||||
"desc": item.Description,
|
||||
"shared_with": item.SharedWith,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenImageListStacks(_ *schema.ResourceData, stack image.ListStacks) []map[string]interface{} {
|
||||
temp := make([]map[string]interface{}, 0)
|
||||
for _, item := range stack {
|
||||
t := map[string]interface{}{
|
||||
"api_url": item.APIURL,
|
||||
"api_key": item.APIKey,
|
||||
"app_id": item.AppID,
|
||||
"desc": item.Description,
|
||||
"drivers": item.Drivers,
|
||||
"error": item.Error,
|
||||
"guid": item.GUID,
|
||||
"id": item.ID,
|
||||
"images": item.Images,
|
||||
"login": item.Login,
|
||||
"name": item.Name,
|
||||
"passwd": item.Password,
|
||||
"reference_id": item.ReferenceID,
|
||||
"status": item.Status,
|
||||
"type": item.Type,
|
||||
}
|
||||
|
||||
temp = append(temp, t)
|
||||
}
|
||||
return temp
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
type History struct {
|
||||
Guid string `json:"guid"`
|
||||
Id int `json:"id"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
ImageId int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
Gid int `json:"gid"`
|
||||
Guid int `json:"guid"`
|
||||
Boottype string `json:"bootType"`
|
||||
Imagetype string `json:"type"`
|
||||
Drivers []string `json:"drivers"`
|
||||
Hotresize bool `json:"hotResize"`
|
||||
Bootable bool `json:"bootable"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
AccountId int `json:"accountId"`
|
||||
UsernameDL string `json:"usernameDL"`
|
||||
PasswordDL string `json:"passwordDL"`
|
||||
SepId int `json:"sepId"`
|
||||
PoolName string `json:"pool"`
|
||||
Architecture string `json:"architecture"`
|
||||
UNCPath string `json:"UNCPath"`
|
||||
LinkTo int `json:"linkTo"`
|
||||
Status string `json:"status"`
|
||||
TechStatus string `json:"techStatus"`
|
||||
Size int `json:"size"`
|
||||
Version string `json:"version"`
|
||||
Enabled bool `json:"enabled"`
|
||||
ComputeciId int `json:"computeciId"`
|
||||
Milestones int `json:"milestones"`
|
||||
ProviderName string `json:"provider_name"`
|
||||
PurgeAttempts int `json:"purgeAttempts"`
|
||||
ReferenceId string `json:"referenceId"`
|
||||
ResId string `json:"resId"`
|
||||
ResName string `json:"resName"`
|
||||
Rescuecd bool `json:"rescuecd"`
|
||||
Meta []interface{} `json:"_meta"`
|
||||
History []History `json:"history"`
|
||||
LastModified int64 `json:"lastModified"`
|
||||
Desc string `json:"desc"`
|
||||
SharedWith []int `json:"sharedWith"`
|
||||
}
|
||||
|
||||
type ImageList []Image
|
||||
|
||||
type ImageStack struct {
|
||||
ApiURL string `json:"apiUrl"`
|
||||
ApiKey string `json:"apikey"`
|
||||
AppId string `json:"appId"`
|
||||
Desc string `json:"desc"`
|
||||
Drivers []string `json:"drivers"`
|
||||
Error int `json:"error"`
|
||||
Guid int `json:"guid"`
|
||||
Id int `json:"id"`
|
||||
Images []int `json:"images"`
|
||||
Login string `json:"login"`
|
||||
Name string `json:"name"`
|
||||
Passwd string `json:"passwd"`
|
||||
ReferenceId string `json:"referenceId"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type ImageListStacks []ImageStack
|
||||
@@ -33,69 +33,57 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceCDROMImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceCDROMImageCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("url", d.Get("url").(string))
|
||||
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
|
||||
|
||||
tstr := d.Get("drivers").([]interface{})
|
||||
temp := ""
|
||||
l := len(tstr)
|
||||
for i, str := range tstr {
|
||||
s := "\"" + str.(string) + "\""
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
req := image.CreateCDROMImageRequest{
|
||||
Name: d.Get("name").(string),
|
||||
URL: d.Get("url").(string),
|
||||
GID: uint64(d.Get("gid").(int)),
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("drivers", temp)
|
||||
|
||||
if username, ok := d.GetOk("username"); ok {
|
||||
urlValues.Add("username", username.(string))
|
||||
drivers := []string{}
|
||||
for _, driver := range d.Get("drivers").([]interface{}) {
|
||||
drivers = append(drivers, driver.(string))
|
||||
}
|
||||
if password, ok := d.GetOk("password"); ok {
|
||||
urlValues.Add("password", password.(string))
|
||||
|
||||
req.Drivers = drivers
|
||||
|
||||
if username, ok := d.GetOk("username_dl"); ok {
|
||||
req.UsernameDL = username.(string)
|
||||
}
|
||||
if password, ok := d.GetOk("password_dl"); ok {
|
||||
req.PasswordDl = password.(string)
|
||||
}
|
||||
if accountId, ok := d.GetOk("account_id"); ok {
|
||||
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
||||
}
|
||||
if usernameDL, ok := d.GetOk("username_dl"); ok {
|
||||
urlValues.Add("usernameDL", usernameDL.(string))
|
||||
}
|
||||
if passwordDL, ok := d.GetOk("password_dl"); ok {
|
||||
urlValues.Add("passwordDL", passwordDL.(string))
|
||||
req.AccountID = uint64(accountId.(int))
|
||||
}
|
||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
|
||||
req.SEPID = uint64(sepId.(int))
|
||||
}
|
||||
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||
urlValues.Add("pool_name", poolName.(string))
|
||||
req.PoolName = poolName.(string)
|
||||
}
|
||||
if architecture, ok := d.GetOk("architecture"); ok {
|
||||
urlValues.Add("architecture", architecture.(string))
|
||||
req.Architecture = architecture.(string)
|
||||
}
|
||||
|
||||
imageId, err := c.DecortAPICall(ctx, "POST", imageCreateCDROMAPI, urlValues)
|
||||
imageId, err := c.CloudBroker().Image().CreateCDROMImage(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(imageId)
|
||||
d.SetId(strconv.FormatUint(imageId, 10))
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
@@ -103,9 +91,7 @@ func resourceCDROMImageCreate(ctx context.Context, d *schema.ResourceData, m int
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(image.ImageId))
|
||||
d.Set("bootable", image.Bootable)
|
||||
//d.Set("image_id", image.ImageId)
|
||||
|
||||
diagnostics := resourceImageRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
@@ -118,26 +104,25 @@ func resourceCDROMImageCreate(ctx context.Context, d *schema.ResourceData, m int
|
||||
func resourceCDROMImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceCDROMImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if image == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
|
||||
if permanently, ok := d.GetOk("permanently"); ok {
|
||||
urlValues.Add("permanently", strconv.FormatBool(permanently.(bool)))
|
||||
}
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", imageDeleteCDROMAPI, urlValues)
|
||||
imageData, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.DeleteCDROMImageRequest{
|
||||
ImageID: imageData.ID,
|
||||
}
|
||||
|
||||
if permanently, ok := d.GetOk("permanently"); ok {
|
||||
req.Permanently = permanently.(bool)
|
||||
}
|
||||
|
||||
_, err = c.CloudBroker().Image().DeleteCDROMImage(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
@@ -192,18 +177,18 @@ func resourceCDROMImageSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
// "username": {
|
||||
// Type: schema.TypeString,
|
||||
// Optional: true,
|
||||
// Computed: true,
|
||||
// Description: "Optional username for the image",
|
||||
// },
|
||||
// "password": {
|
||||
// Type: schema.TypeString,
|
||||
// Optional: true,
|
||||
// Computed: true,
|
||||
// Description: "Optional password for the image",
|
||||
// },
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
@@ -377,7 +362,7 @@ func ResourceCDROMImage() *schema.Resource {
|
||||
|
||||
CreateContext: resourceCDROMImageCreate,
|
||||
ReadContext: resourceImageRead,
|
||||
UpdateContext: resourceImageEdit,
|
||||
UpdateContext: resourceImageUpdate,
|
||||
DeleteContext: resourceCDROMImageDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -33,54 +33,17 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceCreateListImages(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceDeleteListImages(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceDeleteListImages: start deleting...")
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
imageIds := d.Get("image_ids").([]interface{})
|
||||
temp := ""
|
||||
l := len(imageIds)
|
||||
for i, imageId := range imageIds {
|
||||
s := strconv.Itoa(imageId.(int))
|
||||
if i != (l - 1) {
|
||||
s += ",\n"
|
||||
} else {
|
||||
s += "\n"
|
||||
}
|
||||
temp = temp + s
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
|
||||
urlValues.Add("reason", d.Get("reason").(string))
|
||||
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
|
||||
urlValues.Add("imageIds", temp)
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", imageDeleteImagesAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -33,148 +33,84 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("url", d.Get("url").(string))
|
||||
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
|
||||
urlValues.Add("boottype", d.Get("boot_type").(string))
|
||||
urlValues.Add("imagetype", d.Get("image_type").(string))
|
||||
|
||||
tstr := d.Get("drivers").([]interface{})
|
||||
temp := ""
|
||||
l := len(tstr)
|
||||
for i, str := range tstr {
|
||||
s := "\"" + str.(string) + "\""
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
req := image.CreateRequest{
|
||||
Name: d.Get("name").(string),
|
||||
URL: d.Get("url").(string),
|
||||
GID: uint64(d.Get("gid").(int)),
|
||||
BootType: d.Get("boot_type").(string),
|
||||
ImageType: d.Get("image_type").(string),
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("drivers", temp)
|
||||
|
||||
drivers := []string{}
|
||||
for _, driver := range d.Get("drivers").([]interface{}) {
|
||||
drivers = append(drivers, driver.(string))
|
||||
}
|
||||
|
||||
req.Drivers = drivers
|
||||
|
||||
if hotresize, ok := d.GetOk("hot_resize"); ok {
|
||||
urlValues.Add("hotresize", strconv.FormatBool(hotresize.(bool)))
|
||||
req.HotResize = hotresize.(bool)
|
||||
}
|
||||
if username, ok := d.GetOk("username"); ok {
|
||||
urlValues.Add("username", username.(string))
|
||||
req.Username = username.(string)
|
||||
}
|
||||
if password, ok := d.GetOk("password"); ok {
|
||||
urlValues.Add("password", password.(string))
|
||||
req.Password = password.(string)
|
||||
}
|
||||
if accountId, ok := d.GetOk("account_id"); ok {
|
||||
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
||||
req.AccountID = uint64(accountId.(int))
|
||||
}
|
||||
if usernameDL, ok := d.GetOk("username_dl"); ok {
|
||||
urlValues.Add("usernameDL", usernameDL.(string))
|
||||
req.UsernameDL = usernameDL.(string)
|
||||
}
|
||||
if passwordDL, ok := d.GetOk("password_dl"); ok {
|
||||
urlValues.Add("passwordDL", passwordDL.(string))
|
||||
req.PasswordDL = passwordDL.(string)
|
||||
}
|
||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
|
||||
req.SEPID = uint64(sepId.(int))
|
||||
}
|
||||
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||
urlValues.Add("poolName", poolName.(string))
|
||||
req.PoolName = poolName.(string)
|
||||
}
|
||||
if architecture, ok := d.GetOk("architecture"); ok {
|
||||
urlValues.Add("architecture", architecture.(string))
|
||||
req.Architecture = architecture.(string)
|
||||
}
|
||||
|
||||
api := ""
|
||||
if isSync := d.Get("sync").(bool); !isSync {
|
||||
api = imageCreateAPI
|
||||
} else {
|
||||
api = imageSyncCreateAPI
|
||||
}
|
||||
imageId, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||
imageId, err := c.CloudBroker().Image().CreateImage(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(imageId)
|
||||
d.SetId(strconv.FormatUint(imageId, 10))
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(image.ImageId))
|
||||
d.Set("bootable", image.Bootable)
|
||||
//d.Set("image_id", image.ImageId)
|
||||
|
||||
diagnostics := resourceImageRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
return diagnostics
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourceImageRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageRead: called for %s id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if image == nil {
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("name", image.Name)
|
||||
d.Set("drivers", image.Drivers)
|
||||
d.Set("url", image.Url)
|
||||
d.Set("gid", image.Gid)
|
||||
d.Set("image_id", image.ImageId)
|
||||
d.Set("boot_type", image.Boottype)
|
||||
d.Set("image_type", image.Imagetype)
|
||||
d.Set("bootable", image.Bootable)
|
||||
d.Set("sep_id", image.SepId)
|
||||
d.Set("unc_path", image.UNCPath)
|
||||
d.Set("link_to", image.LinkTo)
|
||||
d.Set("status", image.Status)
|
||||
d.Set("tech_status", image.TechStatus)
|
||||
d.Set("version", image.Version)
|
||||
d.Set("size", image.Size)
|
||||
d.Set("enabled", image.Enabled)
|
||||
d.Set("computeci_id", image.ComputeciId)
|
||||
d.Set("pool_name", image.PoolName)
|
||||
d.Set("username", image.Username)
|
||||
d.Set("username_dl", image.UsernameDL)
|
||||
d.Set("password", image.Password)
|
||||
d.Set("password_dl", image.PasswordDL)
|
||||
d.Set("account_id", image.AccountId)
|
||||
d.Set("guid", image.Guid)
|
||||
d.Set("milestones", image.Milestones)
|
||||
d.Set("provider_name", image.ProviderName)
|
||||
d.Set("purge_attempts", image.PurgeAttempts)
|
||||
d.Set("reference_id", image.ReferenceId)
|
||||
d.Set("res_id", image.ResId)
|
||||
d.Set("res_name", image.ResName)
|
||||
d.Set("rescuecd", image.Rescuecd)
|
||||
d.Set("architecture", image.Architecture)
|
||||
d.Set("meta", flattens.FlattenMeta(image.Meta))
|
||||
d.Set("hot_resize", image.Hotresize)
|
||||
d.Set("history", flattenHistory(image.History))
|
||||
d.Set("last_modified", image.LastModified)
|
||||
d.Set("desc", image.Desc)
|
||||
d.Set("shared_with", image.SharedWith)
|
||||
flattenImage(d, image)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -182,30 +118,28 @@ func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if image == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
urlValues.Add("reason", reason.(string))
|
||||
} else {
|
||||
urlValues.Add("reason", "")
|
||||
}
|
||||
if permanently, ok := d.GetOk("permanently"); ok {
|
||||
urlValues.Add("permanently", strconv.FormatBool(permanently.(bool)))
|
||||
}
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", imageDeleteAPI, urlValues)
|
||||
_, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.DeleteRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
}
|
||||
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
req.Reason = reason.(string)
|
||||
}
|
||||
if permanently, ok := d.GetOk("permanently"); ok {
|
||||
req.Permanently = permanently.(bool)
|
||||
}
|
||||
|
||||
_, err = c.CloudBroker().Image().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
@@ -214,10 +148,12 @@ func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
func resourceImageEditName(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageEditName: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
_, err := c.DecortAPICall(ctx, "POST", imageEditNameAPI, urlValues)
|
||||
req := image.RenameRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Image().Rename(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -225,17 +161,15 @@ func resourceImageEditName(ctx context.Context, d *schema.ResourceData, m interf
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
if d.HasChange("enabled") {
|
||||
err := resourceImageChangeEnabled(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("name") {
|
||||
@@ -243,7 +177,6 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("shared_with") {
|
||||
@@ -251,14 +184,13 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("computeci_id") {
|
||||
err := resourceImageChangeComputeci(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("enabled_stacks") {
|
||||
@@ -266,7 +198,6 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChange("link_to") {
|
||||
@@ -274,21 +205,21 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
urlValues = &url.Values{}
|
||||
}
|
||||
|
||||
if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize") {
|
||||
req := image.EditRequest{}
|
||||
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
req.ImageID = uint64(d.Get("image_id").(int))
|
||||
req.Name = d.Get("name").(string)
|
||||
|
||||
urlValues.Add("username", d.Get("username").(string))
|
||||
urlValues.Add("password", d.Get("password").(string))
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("bootable", strconv.FormatBool(d.Get("bootable").(bool)))
|
||||
urlValues.Add("hotresize", strconv.FormatBool(d.Get("hot_resize").(bool)))
|
||||
req.Username = d.Get("username").(string)
|
||||
req.Password = d.Get("password").(string)
|
||||
req.AccountID = uint64(d.Get("account_id").(int))
|
||||
req.Bootable = d.Get("bootable").(bool)
|
||||
req.HotResize = d.Get("hot_resize").(bool)
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", imageEditAPI, urlValues)
|
||||
_, err := c.CloudBroker().Image().Edit(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -298,37 +229,41 @@ func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
}
|
||||
|
||||
func resourceImageChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
var api string
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
imageId := uint64(d.Get("image_id").(int))
|
||||
|
||||
if d.Get("enabled").(bool) {
|
||||
api = imageEnableAPI
|
||||
req := image.EnableRequest{
|
||||
ImageID: imageId,
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Image().Enable(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
api = imageDisableAPI
|
||||
}
|
||||
resp, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := strconv.ParseBool(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !res {
|
||||
return errors.New("Cannot enable/disable")
|
||||
req := image.DisableRequest{
|
||||
ImageID: imageId,
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Image().Disable(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageLink(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceVirtualImageLink: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
urlValues.Add("targetId", strconv.Itoa(d.Get("link_to").(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", imageLinkAPI, urlValues)
|
||||
req := image.LinkRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
TargetID: uint64(d.Get("link_to").(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Image().Link(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -339,23 +274,16 @@ func resourceImageLink(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
func resourceImageShare(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageShare: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
accIds := d.Get("shared_with").([]interface{})
|
||||
temp := ""
|
||||
l := len(accIds)
|
||||
for i, accId := range accIds {
|
||||
s := strconv.Itoa(accId.(int))
|
||||
if i != (l - 1) {
|
||||
s += ",\n"
|
||||
} else {
|
||||
s += "\n"
|
||||
}
|
||||
temp = temp + s
|
||||
req := image.ShareRequest{
|
||||
ImageId: uint64(d.Get("image_id").(int)),
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("accounts", temp)
|
||||
_, err := c.DecortAPICall(ctx, "POST", imageShareAPI, urlValues)
|
||||
accIds := []uint64{}
|
||||
for _, accId := range d.Get("shared_with").([]interface{}) {
|
||||
accIds = append(accIds, uint64(accId.(int)))
|
||||
}
|
||||
req.AccountIDs = accIds
|
||||
|
||||
_, err := c.CloudBroker().Image().Share(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -365,23 +293,29 @@ func resourceImageShare(ctx context.Context, d *schema.ResourceData, m interface
|
||||
|
||||
func resourceImageChangeComputeci(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
computeci := d.Get("computeci_id").(int)
|
||||
|
||||
api := ""
|
||||
imageId := uint64(d.Get("image_id").(int))
|
||||
computeci := uint64(d.Get("computeci_id").(int))
|
||||
|
||||
if computeci == 0 {
|
||||
api = imageComputeciUnsetAPI
|
||||
} else {
|
||||
urlValues.Add("computeciId", strconv.Itoa(computeci))
|
||||
api = imageComputeciSetAPI
|
||||
}
|
||||
req := image.ComputeCIUnsetRequest{
|
||||
ImageID: imageId,
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
_, err := c.CloudBroker().Image().ComputeCIUnset(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
req := image.ComputeCISetRequest{
|
||||
ImageID: imageId,
|
||||
ComputeCIID: computeci,
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Image().ComputeCISet(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -390,21 +324,17 @@ func resourceImageChangeComputeci(ctx context.Context, d *schema.ResourceData, m
|
||||
func resourceImageUpdateNodes(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageUpdateNodes: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
enabledStacks := d.Get("enabled_stacks").([]interface{})
|
||||
temp := ""
|
||||
l := len(enabledStacks)
|
||||
for i, stackId := range enabledStacks {
|
||||
s := stackId.(string)
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
req := image.UpdateNodesRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("enabledStacks", temp)
|
||||
_, err := c.DecortAPICall(ctx, "POST", imageUpdateNodesAPI, urlValues)
|
||||
enabledStacks := []uint64{}
|
||||
for _, stack := range d.Get("enabled_stacks").([]interface{}) {
|
||||
enabledStacks = append(enabledStacks, uint64(stack.(int)))
|
||||
}
|
||||
|
||||
req.EnabledStacks = enabledStacks
|
||||
|
||||
_, err := c.CloudBroker().Image().UpdateNodes(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -661,7 +591,7 @@ func ResourceImage() *schema.Resource {
|
||||
|
||||
CreateContext: resourceImageCreate,
|
||||
ReadContext: resourceImageRead,
|
||||
UpdateContext: resourceImageEdit,
|
||||
UpdateContext: resourceImageUpdate,
|
||||
DeleteContext: resourceImageDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
@@ -679,36 +609,3 @@ func ResourceImage() *schema.Resource {
|
||||
Schema: resourceImageSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
func flattenMeta(m []interface{}) []string {
|
||||
output := []string{}
|
||||
for _, item := range m {
|
||||
switch d := item.(type) {
|
||||
case string:
|
||||
output = append(output, d)
|
||||
case int:
|
||||
output = append(output, strconv.Itoa(d))
|
||||
case int64:
|
||||
output = append(output, strconv.FormatInt(d, 10))
|
||||
case float64:
|
||||
output = append(output, strconv.FormatInt(int64(d), 10))
|
||||
default:
|
||||
output = append(output, "")
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func flattenHistory(history []History) []map[string]interface{} {
|
||||
temp := make([]map[string]interface{}, 0)
|
||||
for _, item := range history {
|
||||
t := map[string]interface{}{
|
||||
"id": item.Id,
|
||||
"guid": item.Guid,
|
||||
"timestamp": item.Timestamp,
|
||||
}
|
||||
|
||||
temp = append(temp, t)
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
@@ -33,47 +33,34 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceVirtualImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("targetId", strconv.Itoa(d.Get("target_id").(int)))
|
||||
req := image.CreateVirtualRequest{
|
||||
Name: d.Get("name").(string),
|
||||
TargetID: uint64(d.Get("target_id").(int)),
|
||||
}
|
||||
|
||||
imageId, err := c.DecortAPICall(ctx, "POST", imageCreateVirtualAPI, urlValues)
|
||||
imageId, err := c.CloudBroker().Image().CreateVirtual(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(imageId)
|
||||
d.SetId(strconv.FormatUint(imageId, 10))
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(image.ImageId))
|
||||
d.Set("bootable", image.Bootable)
|
||||
//d.Set("image_id", image.ImageId)
|
||||
|
||||
diagnostics := resourceImageRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
return diagnostics
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourceImageRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceVirtualImageSchemaMake() map[string]*schema.Schema {
|
||||
@@ -324,7 +311,7 @@ func ResourceVirtualImage() *schema.Resource {
|
||||
|
||||
CreateContext: resourceVirtualImageCreate,
|
||||
ReadContext: resourceImageRead,
|
||||
UpdateContext: resourceImageEdit,
|
||||
UpdateContext: resourceImageUpdate,
|
||||
DeleteContext: resourceImageDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -33,39 +33,28 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Image, error) {
|
||||
func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.RecordImage, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := image.GetRequest{}
|
||||
|
||||
if (strconv.Itoa(d.Get("image_id").(int))) != "0" {
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
req.ImageID = uint64(d.Get("image_id").(int))
|
||||
} else {
|
||||
urlValues.Add("imageId", d.Id())
|
||||
id, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req.ImageID = id
|
||||
}
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", imageGetAPI, urlValues)
|
||||
image, err := c.CloudBroker().Image().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
image := &Image{}
|
||||
if err := json.Unmarshal([]byte(resp), image); err != nil {
|
||||
return nil, errors.New(fmt.Sprint("Can not unmarshall data to image: ", resp, " ", image))
|
||||
}
|
||||
|
||||
return image, nil
|
||||
}
|
||||
|
||||
@@ -33,42 +33,34 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ImageList, error) {
|
||||
imageList := ImageList{}
|
||||
func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (image.ListImages, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := image.ListRequest{}
|
||||
|
||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
|
||||
req.SepID = uint64(sepId.(int))
|
||||
}
|
||||
if sharedWith, ok := d.GetOk("shared_with"); ok {
|
||||
urlValues.Add("sharedWith", strconv.Itoa(sharedWith.(int)))
|
||||
req.SharedWith = uint64(sharedWith.(int))
|
||||
}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityImageListCheckPresence: load image list")
|
||||
imageListRaw, err := c.DecortAPICall(ctx, "POST", imageListGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(imageListRaw), &imageList)
|
||||
imageList, err := c.CloudBroker().Image().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,30 +33,22 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityImageListStacksCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ImageListStacks, error) {
|
||||
imageListStacks := ImageListStacks{}
|
||||
func utilityImageListStacksCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (image.ListStacks, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
|
||||
log.Debugf("utilityImageListStacksCheckPresence: load image list")
|
||||
imageListRaw, err := c.DecortAPICall(ctx, "POST", imageListStacksApi, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := image.ListStacksRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(imageListRaw), &imageListStacks)
|
||||
log.Debugf("utilityImageListStacksCheckPresence: load image list")
|
||||
imageListStacks, err := c.CloudBroker().Image().ListStacks(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -31,43 +31,68 @@ Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/w
|
||||
|
||||
package k8s
|
||||
|
||||
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s"
|
||||
)
|
||||
|
||||
func nodeMasterDefault() K8sNodeRecord {
|
||||
return K8sNodeRecord{
|
||||
func nodeMasterDefault() k8s.MasterGroup {
|
||||
return k8s.MasterGroup{
|
||||
Num: 1,
|
||||
Cpu: 2,
|
||||
Ram: 2048,
|
||||
CPU: 2,
|
||||
RAM: 2048,
|
||||
Disk: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeWorkerDefault() K8sNodeRecord {
|
||||
return K8sNodeRecord{
|
||||
func nodeWorkerDefault() k8s.RecordK8SGroup {
|
||||
return k8s.RecordK8SGroup{
|
||||
Num: 1,
|
||||
Cpu: 1,
|
||||
Ram: 1024,
|
||||
CPU: 1,
|
||||
RAM: 1024,
|
||||
Disk: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func parseNode(nodeList []interface{}) K8sNodeRecord {
|
||||
func parseWorkerNode(nodeList []interface{}) k8s.RecordK8SGroup {
|
||||
node := nodeList[0].(map[string]interface{})
|
||||
|
||||
return K8sNodeRecord{
|
||||
Num: node["num"].(int),
|
||||
Cpu: node["cpu"].(int),
|
||||
Ram: node["ram"].(int),
|
||||
Disk: node["disk"].(int),
|
||||
return k8s.RecordK8SGroup{
|
||||
Num: uint64(node["num"].(int)),
|
||||
CPU: uint64(node["cpu"].(int)),
|
||||
RAM: uint64(node["ram"].(int)),
|
||||
Disk: uint64(node["disk"].(int)),
|
||||
}
|
||||
}
|
||||
|
||||
func nodeToResource(node K8sNodeRecord) []interface{} {
|
||||
func parseMasterNode(nodeList []interface{}) k8s.MasterGroup {
|
||||
node := nodeList[0].(map[string]interface{})
|
||||
|
||||
return k8s.MasterGroup{
|
||||
Num: uint64(node["num"].(int)),
|
||||
CPU: uint64(node["cpu"].(int)),
|
||||
RAM: uint64(node["ram"].(int)),
|
||||
Disk: uint64(node["disk"].(int)),
|
||||
}
|
||||
}
|
||||
|
||||
func workerNodeToResource(node k8s.RecordK8SGroup) []interface{} {
|
||||
mp := make(map[string]interface{})
|
||||
|
||||
mp["num"] = node.Num
|
||||
mp["cpu"] = node.Cpu
|
||||
mp["ram"] = node.Ram
|
||||
mp["cpu"] = node.CPU
|
||||
mp["ram"] = node.RAM
|
||||
mp["disk"] = node.Disk
|
||||
|
||||
return []interface{}{mp}
|
||||
}
|
||||
|
||||
func masterNodeToResource(node k8s.MasterGroup) []interface{} {
|
||||
mp := make(map[string]interface{})
|
||||
|
||||
mp["num"] = node.Num
|
||||
mp["cpu"] = node.CPU
|
||||
mp["ram"] = node.RAM
|
||||
mp["disk"] = node.Disk
|
||||
|
||||
return []interface{}{mp}
|
||||
|
||||
@@ -33,85 +33,84 @@ package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/lb"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceK8sCreate: called with name %s, rg %d", d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int)))
|
||||
urlValues.Add("k8ciId", strconv.Itoa(d.Get("k8sci_id").(int)))
|
||||
urlValues.Add("workerGroupName", d.Get("wg_name").(string))
|
||||
req := k8s.CreateRequest{}
|
||||
|
||||
var masterNode K8sNodeRecord
|
||||
req.Name = d.Get("name").(string)
|
||||
req.RGID = uint64(d.Get("rg_id").(int))
|
||||
req.K8CIID = uint64(d.Get("k8sci_id").(int))
|
||||
req.WorkerGroupName = d.Get("wg_name").(string)
|
||||
|
||||
var masterNode k8s.MasterGroup
|
||||
if masters, ok := d.GetOk("masters"); ok {
|
||||
masterNode = parseNode(masters.([]interface{}))
|
||||
masterNode = parseMasterNode(masters.([]interface{}))
|
||||
} else {
|
||||
masterNode = nodeMasterDefault()
|
||||
}
|
||||
urlValues.Add("masterNum", strconv.Itoa(masterNode.Num))
|
||||
urlValues.Add("masterCpu", strconv.Itoa(masterNode.Cpu))
|
||||
urlValues.Add("masterRam", strconv.Itoa(masterNode.Ram))
|
||||
urlValues.Add("masterDisk", strconv.Itoa(masterNode.Disk))
|
||||
req.MasterNum = uint64(masterNode.Num)
|
||||
req.MasterCPU = uint64(masterNode.CPU)
|
||||
req.MasterRAM = uint64(masterNode.RAM)
|
||||
req.MasterDisk = uint64(masterNode.Disk)
|
||||
|
||||
var workerNode K8sNodeRecord
|
||||
var workerNode k8s.RecordK8SGroup
|
||||
if workers, ok := d.GetOk("workers"); ok {
|
||||
workerNode = parseNode(workers.([]interface{}))
|
||||
workerNode = parseWorkerNode(workers.([]interface{}))
|
||||
} else {
|
||||
workerNode = nodeWorkerDefault()
|
||||
}
|
||||
urlValues.Add("workerNum", strconv.Itoa(workerNode.Num))
|
||||
urlValues.Add("workerCpu", strconv.Itoa(workerNode.Cpu))
|
||||
urlValues.Add("workerRam", strconv.Itoa(workerNode.Ram))
|
||||
urlValues.Add("workerDisk", strconv.Itoa(workerNode.Disk))
|
||||
req.WorkerNum = uint64(workerNode.Num)
|
||||
req.WorkerCPU = uint64(workerNode.CPU)
|
||||
req.WorkerRAM = uint64(workerNode.RAM)
|
||||
req.WorkerDisk = uint64(workerNode.Disk)
|
||||
|
||||
//if withLB, ok := d.GetOk("with_lb"); ok {
|
||||
//urlValues.Add("withLB", strconv.FormatBool(withLB.(bool)))
|
||||
//}
|
||||
urlValues.Add("withLB", strconv.FormatBool(true))
|
||||
|
||||
if extNet, ok := d.GetOk("extnet_id"); ok {
|
||||
urlValues.Add("extnetId", strconv.Itoa(extNet.(int)))
|
||||
if withLB, ok := d.GetOk("with_lb"); ok {
|
||||
req.WithLB = withLB.(bool)
|
||||
} else {
|
||||
urlValues.Add("extnetId", "0")
|
||||
req.WithLB = true
|
||||
}
|
||||
|
||||
//if desc, ok := d.GetOk("desc"); ok {
|
||||
//urlValues.Add("desc", desc.(string))
|
||||
//}
|
||||
if extNet, ok := d.GetOk("extnet_id"); ok {
|
||||
req.ExtNetID = uint64(extNet.(int))
|
||||
} else {
|
||||
req.ExtNetID = 0
|
||||
}
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", K8sCreateAPI, urlValues)
|
||||
if desc, ok := d.GetOk("desc"); ok {
|
||||
req.Description = desc.(string)
|
||||
}
|
||||
|
||||
resp, err := c.CloudBroker().K8S().Create(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
urlValues.Add("auditId", strings.Trim(resp, `"`))
|
||||
tasksReq := tasks.GetRequest{
|
||||
AuditID: resp,
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := c.DecortAPICall(ctx, "POST", AsyncTaskGetAPI, urlValues)
|
||||
task, err := c.CloudBroker().Tasks().Get(ctx, tasksReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
task := AsyncTask{}
|
||||
if err := json.Unmarshal([]byte(resp), &task); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
log.Debugf("resourceK8sCreate: instance creating - %s", task.Stage)
|
||||
|
||||
if task.Completed {
|
||||
@@ -126,78 +125,50 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
time.Sleep(time.Second * 10)
|
||||
}
|
||||
|
||||
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("default_wg_id", k8s.Groups.Workers[0].ID)
|
||||
|
||||
urlValues = &url.Values{}
|
||||
urlValues.Add("lbId", strconv.Itoa(k8s.LbID))
|
||||
|
||||
resp, err = c.DecortAPICall(ctx, "POST", LbGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
var lb LbRecord
|
||||
if err := json.Unmarshal([]byte(resp), &lb); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
d.Set("extnet_id", lb.ExtNetID)
|
||||
d.Set("lb_ip", lb.PrimaryNode.FrontendIP)
|
||||
|
||||
urlValues = &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
kubeconfig, err := c.DecortAPICall(ctx, "POST", K8sGetConfigAPI, urlValues)
|
||||
if err != nil {
|
||||
log.Warnf("could not get kubeconfig: %v", err)
|
||||
}
|
||||
d.Set("kubeconfig", kubeconfig)
|
||||
|
||||
return nil
|
||||
return resourceK8sRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceK8sRead: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||
|
||||
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if k8s == nil {
|
||||
k8sData, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("name", k8s.Name)
|
||||
d.Set("rg_id", k8s.RgID)
|
||||
d.Set("k8sci_id", k8s.CI)
|
||||
d.Set("wg_name", k8s.Groups.Workers[0].Name)
|
||||
d.Set("masters", nodeToResource(k8s.Groups.Masters))
|
||||
d.Set("workers", nodeToResource(k8s.Groups.Workers[0]))
|
||||
d.Set("default_wg_id", k8s.Groups.Workers[0].ID)
|
||||
d.Set("name", k8sData.Name)
|
||||
d.Set("rg_id", k8sData.RGID)
|
||||
d.Set("k8sci_id", k8sData.CIID)
|
||||
d.Set("wg_name", k8sData.K8SGroups.Workers[0].Name)
|
||||
d.Set("masters", masterNodeToResource(k8sData.K8SGroups.Masters))
|
||||
d.Set("workers", workerNodeToResource(k8sData.K8SGroups.Workers[0]))
|
||||
d.Set("default_wg_id", k8sData.K8SGroups.Workers[0].ID)
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("lbId", strconv.Itoa(k8s.LbID))
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", LbGetAPI, urlValues)
|
||||
lbReq := lb.GetRequest{
|
||||
LBID: k8sData.LBID,
|
||||
}
|
||||
|
||||
lbData, err := c.CloudBroker().LB().Get(ctx, lbReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
var lb LbRecord
|
||||
if err := json.Unmarshal([]byte(resp), &lb); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
d.Set("extnet_id", lb.ExtNetID)
|
||||
d.Set("lb_ip", lb.PrimaryNode.FrontendIP)
|
||||
d.Set("extnet_id", lbData.ExtNetID)
|
||||
d.Set("lb_ip", lbData.PrimaryNode.FrontendIP)
|
||||
|
||||
urlValues = &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
kubeconfig, err := c.DecortAPICall(ctx, "POST", K8sGetConfigAPI, urlValues)
|
||||
configReq := k8s.GetConfigRequest{
|
||||
K8SID: k8sData.ID,
|
||||
}
|
||||
|
||||
kubeconfig, err := c.CloudBroker().K8S().GetConfig(ctx, configReq)
|
||||
if err != nil {
|
||||
log.Warnf("could not get kubeconfig: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
d.Set("kubeconfig", kubeconfig)
|
||||
|
||||
return nil
|
||||
@@ -207,40 +178,47 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
log.Debugf("resourceK8sUpdate: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
k8sId, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
if d.HasChange("name") {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
req := k8s.UpdateRequest{
|
||||
K8SID: k8sId,
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", K8sUpdateAPI, urlValues)
|
||||
_, err := c.CloudBroker().K8S().Update(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("workers") {
|
||||
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
k8sData, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
wg := k8s.Groups.Workers[0]
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
urlValues.Add("workersGroupId", strconv.Itoa(wg.ID))
|
||||
wg := k8sData.K8SGroups.Workers[0]
|
||||
deleteReq := k8s.DeleteWorkerFromGroupRequest{
|
||||
K8SID: k8sId,
|
||||
WorkersGroupID: wg.ID,
|
||||
}
|
||||
addReq := k8s.WorkerAddRequest{
|
||||
K8SID: k8sId,
|
||||
WorkersGroupID: wg.ID,
|
||||
}
|
||||
|
||||
newWorkers := parseNode(d.Get("workers").([]interface{}))
|
||||
newWorkers := parseWorkerNode(d.Get("workers").([]interface{}))
|
||||
|
||||
if newWorkers.Num > wg.Num {
|
||||
urlValues.Add("num", strconv.Itoa(newWorkers.Num-wg.Num))
|
||||
if _, err := c.DecortAPICall(ctx, "POST", K8sWorkerAddAPI, urlValues); err != nil {
|
||||
addReq.Num = uint64(newWorkers.Num - wg.Num)
|
||||
if _, err := c.CloudBroker().K8S().WorkerAdd(ctx, addReq); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
for i := wg.Num - 1; i >= newWorkers.Num; i-- {
|
||||
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
|
||||
if _, err := c.DecortAPICall(ctx, "POST", K8sWorkerDeleteAPI, urlValues); err != nil {
|
||||
deleteReq.WorkerID = wg.DetailedInfo[i].ID
|
||||
if _, err := c.CloudBroker().K8S().DeleteWorkerFromGroup(ctx, deleteReq); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
@@ -253,20 +231,22 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||
|
||||
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if k8s == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
k8sData, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
urlValues.Add("permanently", "true")
|
||||
req := k8s.DeleteRequest{
|
||||
K8SID: k8sData.ID,
|
||||
}
|
||||
if perm, ok := d.GetOk("permanently"); ok {
|
||||
req.Permanently = perm.(bool)
|
||||
} else {
|
||||
req.Permanently = false
|
||||
}
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", K8sDeleteAPI, urlValues)
|
||||
_, err = c.CloudBroker().K8S().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
@@ -33,12 +33,11 @@ package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
@@ -47,15 +46,16 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
log.Debugf("resourceK8sWgCreate: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("workerNum", strconv.Itoa(d.Get("num").(int)))
|
||||
urlValues.Add("workerCpu", strconv.Itoa(d.Get("cpu").(int)))
|
||||
urlValues.Add("workerRam", strconv.Itoa(d.Get("ram").(int)))
|
||||
urlValues.Add("workerDisk", strconv.Itoa(d.Get("disk").(int)))
|
||||
req := k8s.WorkersGroupAddRequest{
|
||||
K8SID: uint64(d.Get("k8s_id").(int)),
|
||||
Name: d.Get("name").(string),
|
||||
WorkerNum: uint64(d.Get("num").(int)),
|
||||
WorkerCPU: uint64(d.Get("cpu").(int)),
|
||||
WorkerRAM: uint64(d.Get("ram").(int)),
|
||||
WorkerDisk: uint64(d.Get("disk").(int)),
|
||||
}
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", K8sWgCreateAPI, urlValues)
|
||||
resp, err := c.CloudBroker().K8S().WorkersGroupAdd(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -69,15 +69,15 @@ func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
log.Debugf("resourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
|
||||
if wg == nil {
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("name", wg.Name)
|
||||
d.Set("num", wg.Num)
|
||||
d.Set("cpu", wg.Cpu)
|
||||
d.Set("ram", wg.Ram)
|
||||
d.Set("cpu", wg.CPU)
|
||||
d.Set("ram", wg.RAM)
|
||||
d.Set("disk", wg.Disk)
|
||||
|
||||
return nil
|
||||
@@ -93,20 +93,26 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
urlValues.Add("workersGroupId", d.Id())
|
||||
addReq := k8s.WorkerAddRequest{
|
||||
K8SID: uint64(d.Get("k8s_id").(int)),
|
||||
WorkersGroupID: wg.ID,
|
||||
}
|
||||
|
||||
if newNum := d.Get("num").(int); newNum > wg.Num {
|
||||
urlValues.Add("num", strconv.Itoa(newNum-wg.Num))
|
||||
_, err := c.DecortAPICall(ctx, "POST", K8sWorkerAddAPI, urlValues)
|
||||
delReq := k8s.DeleteWorkerFromGroupRequest{
|
||||
K8SID: uint64(d.Get("k8s_id").(int)),
|
||||
WorkersGroupID: wg.ID,
|
||||
}
|
||||
|
||||
if newNum := uint64(d.Get("num").(int)); newNum > wg.Num {
|
||||
addReq.Num = newNum - wg.Num
|
||||
_, err := c.CloudBroker().K8S().WorkerAdd(ctx, addReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
for i := wg.Num - 1; i >= newNum; i-- {
|
||||
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
|
||||
_, err := c.DecortAPICall(ctx, "POST", K8sWorkerDeleteAPI, urlValues)
|
||||
delReq.WorkerID = wg.DetailedInfo[i].ID
|
||||
_, err := c.CloudBroker().K8S().DeleteWorkerFromGroup(ctx, delReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -120,23 +126,23 @@ func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
|
||||
if wg == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
urlValues.Add("workersGroupId", strconv.Itoa(wg.ID))
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", K8sWgDeleteAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := k8s.WorkersGroupDeleteRequest{
|
||||
K8SID: uint64(d.Get("k8s_id").(int)),
|
||||
WorkersGroupID: wg.ID,
|
||||
}
|
||||
|
||||
_, err = c.CloudBroker().K8S().WorkersGroupDelete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -33,31 +33,24 @@ package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8sRecord, error) {
|
||||
func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8S, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
req := k8s.GetRequest{}
|
||||
k8sId, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues)
|
||||
req.K8SID = k8sId
|
||||
|
||||
k8s, err := c.CloudBroker().K8S().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var k8s K8sRecord
|
||||
if err := json.Unmarshal([]byte(resp), &k8s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &k8s, nil
|
||||
return k8s, nil
|
||||
}
|
||||
|
||||
@@ -33,40 +33,28 @@ package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8sNodeRecord, error) {
|
||||
func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*k8s.RecordK8SGroup, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
req := k8s.GetRequest{
|
||||
K8SID: uint64(d.Get("k8s_id").(int)),
|
||||
}
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues)
|
||||
k8sData, err := c.CloudBroker().K8S().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
}
|
||||
k8sWgID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
var k8s K8sRecord
|
||||
if err := json.Unmarshal([]byte(resp), &k8s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
id, err := strconv.Atoi(d.Id())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, wg := range k8s.Groups.Workers {
|
||||
if wg.ID == id {
|
||||
for _, wg := range k8sData.K8SGroups.Workers {
|
||||
if wg.ID == k8sWgID {
|
||||
return &wg, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ package kvmvm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
// "net/url"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -48,7 +48,7 @@ import (
|
||||
|
||||
// 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.
|
||||
func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
||||
func parseComputeDisksToExtraDisks(disks compute.ListDisks) []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)
|
||||
@@ -76,7 +76,7 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
||||
return result
|
||||
}
|
||||
|
||||
func findBootDisk(disks []DiskRecord) *DiskRecord {
|
||||
func findBootDisk(disks compute.ListDisks) *compute.ItemDisk {
|
||||
for _, d := range disks {
|
||||
if d.Type == "B" {
|
||||
return &d
|
||||
@@ -84,12 +84,12 @@ func findBootDisk(disks []DiskRecord) *DiskRecord {
|
||||
}
|
||||
|
||||
// some computes don't have a boot disk, so...
|
||||
return &DiskRecord{}
|
||||
return &compute.ItemDisk{}
|
||||
}
|
||||
|
||||
// Parse the list of interfaces from compute/get response into a list of networks
|
||||
// attached to this compute
|
||||
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
||||
func parseComputeInterfacesToNetworks(ifaces compute.ListInterfaces) []interface{} {
|
||||
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
||||
length := len(ifaces)
|
||||
log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length)
|
||||
@@ -113,68 +113,58 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
||||
return result
|
||||
}
|
||||
|
||||
func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||
func flattenCompute(d *schema.ResourceData, compFacts *compute.RecordCompute) error {
|
||||
// This function expects that compFacts string contains response from API compute/get,
|
||||
// i.e. detailed information about compute instance.
|
||||
//
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourceComputeExists(...) method
|
||||
model := ComputeGetResp{}
|
||||
log.Debugf("flattenCompute: ready to unmarshal string %s", compFacts)
|
||||
err := json.Unmarshal([]byte(compFacts), &model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("flattenCompute: ID %d, RG ID %d", model.ID, model.RgID)
|
||||
log.Debugf("flattenCompute: ID %d, RG ID %d", compFacts.ID, compFacts.RGID)
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", model.ID))
|
||||
// d.Set("compute_id", model.ID) - we should NOT set compute_id in the schema here: if it was set - it is already set, if it wasn't - we shouldn't
|
||||
d.Set("name", model.Name)
|
||||
d.Set("rg_id", model.RgID)
|
||||
d.Set("rg_name", model.RgName)
|
||||
d.Set("account_id", model.AccountID)
|
||||
d.Set("account_name", model.AccountName)
|
||||
d.Set("driver", model.Driver)
|
||||
d.Set("cpu", model.Cpu)
|
||||
d.Set("ram", model.Ram)
|
||||
// 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("image_id", model.ImageID)
|
||||
d.Set("description", model.Desc)
|
||||
d.Set("cloud_init", "applied") // NOTE: for existing compute we hard-code this value as an indicator for DiffSuppress fucntion
|
||||
// d.Set("status", model.Status)
|
||||
// d.Set("tech_status", model.TechStatus)
|
||||
d.SetId(fmt.Sprintf("%d", compFacts.ID))
|
||||
d.Set("name", compFacts.Name)
|
||||
d.Set("rg_id", compFacts.RGID)
|
||||
d.Set("rg_name", compFacts.RGName)
|
||||
d.Set("account_id", compFacts.AccountID)
|
||||
d.Set("account_name", compFacts.AccountName)
|
||||
d.Set("driver", compFacts.Driver)
|
||||
d.Set("cpu", compFacts.CPUs)
|
||||
d.Set("ram", compFacts.RAM)
|
||||
d.Set("image_id", compFacts.ImageID)
|
||||
d.Set("description", compFacts.Description)
|
||||
d.Set("cloud_init", "applied")
|
||||
|
||||
if model.TechStatus == "STARTED" {
|
||||
if compFacts.TechStatus == "STARTED" {
|
||||
d.Set("started", true)
|
||||
} else {
|
||||
d.Set("started", false)
|
||||
}
|
||||
|
||||
bootDisk := findBootDisk(model.Disks)
|
||||
bootDisk := findBootDisk(compFacts.Disks)
|
||||
|
||||
d.Set("boot_disk_size", bootDisk.SizeMax)
|
||||
d.Set("boot_disk_id", bootDisk.ID) // we may need boot disk ID in resize operations
|
||||
d.Set("sep_id", bootDisk.SepID)
|
||||
d.Set("sep_id", bootDisk.SEPID)
|
||||
d.Set("pool", bootDisk.Pool)
|
||||
|
||||
if len(model.Disks) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(model.Disks))
|
||||
if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil {
|
||||
if len(compFacts.Disks) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(compFacts.Disks))
|
||||
if err := d.Set("extra_disks", parseComputeDisksToExtraDisks(compFacts.Disks)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(model.Interfaces) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(model.Interfaces))
|
||||
if err = d.Set("network", parseComputeInterfacesToNetworks(model.Interfaces)); err != nil {
|
||||
if len(compFacts.Interfaces) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(compFacts.Interfaces))
|
||||
if err := d.Set("network", parseComputeInterfacesToNetworks(compFacts.Interfaces)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(model.OsUsers) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseOsUsers for %d logins", len(model.OsUsers))
|
||||
if err = d.Set("os_users", parseOsUsers(model.OsUsers)); err != nil {
|
||||
if len(compFacts.OSUsers) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseOsUsers for %d logins", len(compFacts.OSUsers))
|
||||
if err := d.Set("os_users", parseOsUsers(compFacts.OSUsers)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -184,10 +174,8 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||
|
||||
func dataSourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
compFacts, err := utilityComputeCheckPresence(ctx, d, m)
|
||||
if compFacts == "" {
|
||||
// if empty string is returned from utilityComputeCheckPresence then there is no
|
||||
// such Compute and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty
|
||||
if compFacts == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
@@ -277,7 +265,6 @@ func DataSourceCompute() *schema.Resource {
|
||||
Computed: true,
|
||||
Description: "Name of the OS image this compute instance is based on.",
|
||||
},
|
||||
|
||||
"boot_disk_size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
|
||||
@@ -33,17 +33,18 @@ package kvmvm
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func parseOsUsers(logins []OsUserRecord) []interface{} {
|
||||
func parseOsUsers(logins compute.ListOSUsers) []interface{} {
|
||||
var result = make([]interface{}, len(logins))
|
||||
|
||||
for index, value := range logins {
|
||||
elem := make(map[string]interface{})
|
||||
|
||||
elem["guid"] = value.Guid
|
||||
elem["guid"] = value.GUID
|
||||
elem["login"] = value.Login
|
||||
elem["password"] = value.Password
|
||||
elem["public_key"] = value.PubKey
|
||||
|
||||
@@ -33,14 +33,16 @@ package kvmvm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/disks"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/kvmppc"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/kvmx86"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -49,110 +51,112 @@ import (
|
||||
|
||||
func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
|
||||
if oldVal == "" && newVal != "applied" {
|
||||
// if old value for "cloud_init" resource is empty string, it means that we are creating new compute
|
||||
// and there is a chance that the user will want custom cloud init parameters - so we check if
|
||||
// cloud_init is explicitly set in TF file by making sure that its new value is different from "applied",
|
||||
// which is a reserved key word.
|
||||
log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal)
|
||||
return false // there is a difference between stored and new value
|
||||
return false
|
||||
}
|
||||
log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal)
|
||||
return true // suppress difference
|
||||
return true
|
||||
}
|
||||
|
||||
func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
// 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
|
||||
|
||||
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
|
||||
// by subsequent individual API calls).
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", d.Get("rg_id").(int)))
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("cpu", fmt.Sprintf("%d", d.Get("cpu").(int)))
|
||||
urlValues.Add("ram", fmt.Sprintf("%d", d.Get("ram").(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("netType", "NONE") // at the 1st step create isolated compute
|
||||
urlValues.Add("start", "0") // at the 1st step create compute in a stopped state
|
||||
reqPPC := kvmppc.CreateRequest{}
|
||||
reqX86 := kvmx86.CreateRequest{}
|
||||
|
||||
reqPPC.RGID = uint64(d.Get("rg_id").(int))
|
||||
reqX86.RGID = uint64(d.Get("rg_id").(int))
|
||||
|
||||
reqPPC.Name = d.Get("name").(string)
|
||||
reqX86.Name = d.Get("name").(string)
|
||||
|
||||
reqPPC.CPU = uint64(d.Get("cpu").(int))
|
||||
reqPPC.RAM = uint64(d.Get("ram").(int))
|
||||
reqPPC.ImageID = uint64(d.Get("image_id").(int))
|
||||
reqPPC.BootDisk = uint64(d.Get("boot_disk_size").(int))
|
||||
reqPPC.NetType = "NONE"
|
||||
reqPPC.Start = false
|
||||
|
||||
reqX86.CPU = uint64(d.Get("cpu").(int))
|
||||
reqX86.RAM = uint64(d.Get("ram").(int))
|
||||
reqX86.ImageID = uint64(d.Get("image_id").(int))
|
||||
reqX86.BootDisk = uint64(d.Get("boot_disk_size").(int))
|
||||
reqX86.NetType = "NONE"
|
||||
reqX86.Start = false
|
||||
|
||||
argVal, argSet := d.GetOk("description")
|
||||
if argSet {
|
||||
urlValues.Add("desc", argVal.(string))
|
||||
reqPPC.Description = argVal.(string)
|
||||
reqX86.Description = argVal.(string)
|
||||
}
|
||||
|
||||
if sepID, ok := d.GetOk("sep_id"); ok {
|
||||
urlValues.Add("sepId", strconv.Itoa(sepID.(int)))
|
||||
reqPPC.SEPID = uint64(sepID.(int))
|
||||
reqX86.SEPID = uint64(sepID.(int))
|
||||
}
|
||||
|
||||
if pool, ok := d.GetOk("pool"); ok {
|
||||
urlValues.Add("pool", pool.(string))
|
||||
}
|
||||
|
||||
/*
|
||||
sshKeysVal, sshKeysSet := d.GetOk("ssh_keys")
|
||||
if sshKeysSet {
|
||||
// process SSH Key settings and set API values accordingly
|
||||
log.Debugf("resourceComputeCreate: calling makeSshKeysArgString to setup SSH keys for guest login(s)")
|
||||
urlValues.Add("userdata", makeSshKeysArgString(sshKeysVal.([]interface{})))
|
||||
}
|
||||
*/
|
||||
|
||||
computeCreateAPI := KvmX86CreateAPI
|
||||
driver := d.Get("driver").(string)
|
||||
if driver == "KVM_PPC" {
|
||||
computeCreateAPI = KvmPPCCreateAPI
|
||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC")
|
||||
} else { // note that we do not validate arch value for explicit "KVM_X86" here
|
||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
|
||||
reqPPC.Pool = pool.(string)
|
||||
reqX86.Pool = pool.(string)
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("cloud_init")
|
||||
if argSet {
|
||||
// userdata must not be empty string and must not be a reserved keyword "applied"
|
||||
userdata := argVal.(string)
|
||||
if userdata != "" && userdata != "applied" {
|
||||
urlValues.Add("userdata", userdata)
|
||||
reqPPC.Userdata = userdata
|
||||
reqX86.Userdata = userdata
|
||||
}
|
||||
}
|
||||
|
||||
apiResp, err := c.DecortAPICall(ctx, "POST", computeCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
// Compute create API returns ID of the new Compute instance on success
|
||||
var createdID uint64
|
||||
driver := d.Get("driver").(string)
|
||||
if driver == "KVM_PPC" {
|
||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC")
|
||||
id, err := c.CloudBroker().KVMPPC().Create(ctx, reqPPC)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(apiResp) // update ID of the resource to tell Terraform that the resource exists, albeit partially
|
||||
compId, _ := strconv.Atoi(apiResp)
|
||||
createdID = id
|
||||
} else {
|
||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
|
||||
id, err := c.CloudBroker().KVMX86().Create(ctx, reqX86)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
createdID = id
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(createdID, 10))
|
||||
|
||||
cleanup := false
|
||||
defer func() {
|
||||
if cleanup {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("permanently", "1")
|
||||
urlValues.Add("detachDisks", "1")
|
||||
req := compute.DeleteRequest{
|
||||
ComputeID: createdID,
|
||||
Permanently: true,
|
||||
DetachDisks: true,
|
||||
}
|
||||
|
||||
if _, err := c.DecortAPICall(ctx, "POST", ComputeDeleteAPI, urlValues); err != nil {
|
||||
if _, err := c.CloudBroker().Compute().Delete(ctx, req); err != nil {
|
||||
log.Errorf("resourceComputeCreate: could not delete compute after failed creation: %v", err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
}
|
||||
}()
|
||||
|
||||
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", createdID, d.Get("name").(string))
|
||||
|
||||
// Configure data disks if any
|
||||
argVal, argSet = d.GetOk("extra_disks")
|
||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||
// urlValues.Add("desc", argVal.(string))
|
||||
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
|
||||
err = utilityComputeExtraDisksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute
|
||||
err := utilityComputeExtraDisksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute
|
||||
if err != nil {
|
||||
log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", compId, err)
|
||||
log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", createdID, err)
|
||||
cleanup = true
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -161,32 +165,28 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
argVal, argSet = d.GetOk("network")
|
||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||
log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len())
|
||||
err = utilityComputeNetworksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute
|
||||
err := utilityComputeNetworksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute
|
||||
if err != nil {
|
||||
log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", compId, err)
|
||||
log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", createdID, err)
|
||||
cleanup = true
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
if d.Get("started").(bool) {
|
||||
reqValues := &url.Values{}
|
||||
reqValues.Add("computeId", fmt.Sprintf("%d", compId))
|
||||
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId)
|
||||
if _, err := c.DecortAPICall(ctx, "POST", ComputeStartAPI, reqValues); err != nil {
|
||||
req := compute.StartRequest{
|
||||
ComputeID: createdID,
|
||||
}
|
||||
|
||||
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", createdID)
|
||||
if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil {
|
||||
cleanup = true
|
||||
return diag.FromErr(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", createdID, d.Get("name").(string))
|
||||
|
||||
// We may reuse dataSourceComputeRead here as we maintain similarity
|
||||
// between Compute resource and Compute data source schemas
|
||||
// Compute read function will also update resource ID on success, so that Terraform
|
||||
// will know the resource exists
|
||||
return dataSourceComputeRead(ctx, d, m)
|
||||
}
|
||||
|
||||
@@ -195,11 +195,11 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
compFacts, err := utilityComputeCheckPresence(ctx, d, m)
|
||||
if compFacts == "" {
|
||||
if compFacts == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
// Compute with such name and RG ID was not found
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -218,6 +218,7 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
d.Id(), d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
computeID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
/*
|
||||
1. Resize CPU/RAM
|
||||
@@ -228,32 +229,34 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
*/
|
||||
|
||||
// 1. Resize CPU/RAM
|
||||
params := &url.Values{}
|
||||
resizeReq := compute.ResizeRequest{
|
||||
ComputeID: computeID,
|
||||
Force: true,
|
||||
}
|
||||
doUpdate := false
|
||||
params.Add("computeId", d.Id())
|
||||
|
||||
oldCpu, newCpu := d.GetChange("cpu")
|
||||
if oldCpu.(int) != newCpu.(int) {
|
||||
params.Add("cpu", fmt.Sprintf("%d", newCpu.(int)))
|
||||
resizeReq.CPU = uint64(newCpu.(int))
|
||||
doUpdate = true
|
||||
} else {
|
||||
params.Add("cpu", "0") // no change to CPU allocation
|
||||
resizeReq.CPU = 0
|
||||
}
|
||||
|
||||
oldRam, newRam := d.GetChange("ram")
|
||||
if oldRam.(int) != newRam.(int) {
|
||||
params.Add("ram", fmt.Sprintf("%d", newRam.(int)))
|
||||
resizeReq.RAM = uint64(newRam.(int))
|
||||
doUpdate = true
|
||||
} else {
|
||||
params.Add("ram", "0")
|
||||
resizeReq.RAM = 0
|
||||
}
|
||||
|
||||
if doUpdate {
|
||||
log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d",
|
||||
oldCpu.(int), newCpu.(int),
|
||||
oldRam.(int), newRam.(int))
|
||||
params.Add("force", "true")
|
||||
_, err := c.DecortAPICall(ctx, "POST", ComputeResizeAPI, params)
|
||||
|
||||
_, err := c.CloudBroker().Compute().Resize(ctx, resizeReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -262,12 +265,15 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
// 2. Resize (grow) Boot disk
|
||||
oldSize, newSize := d.GetChange("boot_disk_size")
|
||||
if oldSize.(int) < newSize.(int) {
|
||||
bdsParams := &url.Values{}
|
||||
bdsParams.Add("diskId", fmt.Sprintf("%d", d.Get("boot_disk_id").(int)))
|
||||
bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
||||
req := disks.ResizeRequest{
|
||||
DiskID: uint64(d.Get("boot_disk_id").(int)),
|
||||
Size: uint64(newSize.(int)),
|
||||
}
|
||||
|
||||
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))
|
||||
_, err := c.DecortAPICall(ctx, "POST", DisksResizeAPI, bdsParams)
|
||||
|
||||
_, err := c.CloudBroker().Disks().Resize(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -288,14 +294,18 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
}
|
||||
|
||||
if d.HasChange("started") {
|
||||
params := &url.Values{}
|
||||
params.Add("computeId", d.Id())
|
||||
if d.Get("started").(bool) {
|
||||
if _, err := c.DecortAPICall(ctx, "POST", ComputeStartAPI, params); err != nil {
|
||||
req := compute.StartRequest{
|
||||
ComputeID: computeID,
|
||||
}
|
||||
if _, err := c.CloudBroker().Compute().Start(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
if _, err := c.DecortAPICall(ctx, "POST", ComputeStopAPI, params); err != nil {
|
||||
req := compute.StopRequest{
|
||||
ComputeID: computeID,
|
||||
}
|
||||
if _, err := c.CloudBroker().Compute().Stop(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
@@ -307,21 +317,19 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
}
|
||||
|
||||
func resourceComputeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
// NOTE: this function destroys target Compute instance "permanently", so
|
||||
// there is no way to restore it.
|
||||
// If compute being destroyed has some extra disks attached, they are
|
||||
// detached from the compute
|
||||
log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d",
|
||||
d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
computeID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
params := &url.Values{}
|
||||
params.Add("computeId", d.Id())
|
||||
params.Add("permanently", "1")
|
||||
params.Add("detachDisks", "1")
|
||||
req := compute.DeleteRequest{
|
||||
ComputeID: computeID,
|
||||
Permanently: d.Get("permanently").(bool),
|
||||
DetachDisks: d.Get("detach_disks").(bool),
|
||||
}
|
||||
|
||||
if _, err := c.DecortAPICall(ctx, "POST", ComputeDeleteAPI, params); err != nil {
|
||||
if _, err := c.CloudBroker().Compute().Delete(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,31 +33,23 @@ package kvmvm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error {
|
||||
// d is filled with data according to computeResource schema, so extra disks config is retrieved via "extra_disks" key
|
||||
// If do_delta is true, this function will identify changes between new and existing specs for extra disks and try to
|
||||
// update compute configuration accordingly
|
||||
// Otherwise it will apply whatever is found in the new set of "extra_disks" right away.
|
||||
// Primary use of do_delta=false is when calling this function from compute Create handler.
|
||||
|
||||
// Note that this function will not abort on API errors, but will continue to configure (attach / detach) other individual
|
||||
// disks via atomic API calls. However, it will not retry failed manipulation on the same disk.
|
||||
c := m.(*controller.ControllerCfg)
|
||||
computeID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta)
|
||||
|
||||
// NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt
|
||||
old_set, new_set := d.GetChange("extra_disks")
|
||||
|
||||
apiErrCount := 0
|
||||
@@ -69,12 +61,13 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa
|
||||
}
|
||||
|
||||
for _, disk := range new_set.(*schema.Set).List() {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", ComputeDiskAttachAPI, urlValues)
|
||||
req := compute.DiskAttachRequest{
|
||||
ComputeID: computeID,
|
||||
DiskID: uint64(disk.(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Compute().DiskAttach(ctx, req)
|
||||
if err != nil {
|
||||
// failed to attach extra disk - partial resource update
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
@@ -92,10 +85,12 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa
|
||||
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
|
||||
log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
|
||||
for _, diskId := range detach_set.List() {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", ComputeDiskDetachAPI, urlValues)
|
||||
req := compute.DiskDetachRequest{
|
||||
ComputeID: computeID,
|
||||
DiskID: uint64(diskId.(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Compute().DiskDetach(ctx, req)
|
||||
if err != nil {
|
||||
// failed to detach disk - there will be partial resource update
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||
@@ -107,10 +102,12 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa
|
||||
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
|
||||
log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
|
||||
for _, diskId := range attach_set.List() {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", ComputeDiskAttachAPI, urlValues)
|
||||
req := compute.DiskAttachRequest{
|
||||
ComputeID: computeID,
|
||||
DiskID: uint64(diskId.(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Compute().DiskAttach(ctx, req)
|
||||
if err != nil {
|
||||
// failed to attach disk - there will be partial resource update
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||
@@ -129,13 +126,8 @@ func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceDa
|
||||
}
|
||||
|
||||
func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error {
|
||||
// "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key
|
||||
// If do_delta is true, this function will identify changes between new and existing specs for network and try to
|
||||
// update compute configuration accordingly
|
||||
// Otherwise it will apply whatever is found in the new set of "network" right away.
|
||||
// Primary use of do_delta=false is when calling this function from compute Create handler.
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
computeID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
old_set, new_set := d.GetChange("network")
|
||||
|
||||
@@ -148,18 +140,19 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
|
||||
}
|
||||
|
||||
for _, runner := range new_set.(*schema.Set).List() {
|
||||
urlValues := &url.Values{}
|
||||
net_data := runner.(map[string]interface{})
|
||||
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["ip_address"] // "ip_address" key is optional
|
||||
if ipSet {
|
||||
urlValues.Add("ipAddr", ipaddr.(string))
|
||||
req := compute.NetAttachRequest{
|
||||
ComputeID: computeID,
|
||||
NetType: net_data["net_type"].(string),
|
||||
NetID: uint64(net_data["net_id"].(int)),
|
||||
}
|
||||
_, err := c.DecortAPICall(ctx, "POST", ComputeNetAttachAPI, urlValues)
|
||||
|
||||
ipaddr, ipSet := net_data["ip_address"]
|
||||
if ipSet {
|
||||
req.IPAddr = ipaddr.(string)
|
||||
}
|
||||
_, err := c.CloudBroker().Compute().NetAttach(ctx, req)
|
||||
if err != nil {
|
||||
// failed to attach network - partial resource update
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
@@ -176,12 +169,14 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
|
||||
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
|
||||
log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
|
||||
for _, runner := range detach_set.List() {
|
||||
urlValues := &url.Values{}
|
||||
net_data := runner.(map[string]interface{})
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
||||
urlValues.Add("mac", net_data["mac"].(string))
|
||||
_, err := c.DecortAPICall(ctx, "POST", ComputeNetDetachAPI, urlValues)
|
||||
req := compute.NetDetachRequest{
|
||||
ComputeID: computeID,
|
||||
IPAddr: net_data["ip_address"].(string),
|
||||
MAC: net_data["mac"].(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Compute().NetDetach(ctx, req)
|
||||
if err != nil {
|
||||
// failed to detach this network - there will be partial resource update
|
||||
log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s",
|
||||
@@ -194,15 +189,18 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
|
||||
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
|
||||
log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
|
||||
for _, runner := range attach_set.List() {
|
||||
urlValues := &url.Values{}
|
||||
net_data := runner.(map[string]interface{})
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
|
||||
urlValues.Add("netType", net_data["net_type"].(string))
|
||||
if net_data["ip_address"].(string) != "" {
|
||||
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
||||
req := compute.NetAttachRequest{
|
||||
ComputeID: computeID,
|
||||
NetID: uint64(net_data["net_id"].(int)),
|
||||
NetType: net_data["net_type"].(string),
|
||||
}
|
||||
_, err := c.DecortAPICall(ctx, "POST", ComputeNetAttachAPI, urlValues)
|
||||
|
||||
if net_data["ip_address"].(string) != "" {
|
||||
req.IPAddr = net_data["ip_address"].(string)
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().Compute().NetAttach(ctx, req)
|
||||
if err != nil {
|
||||
// failed to attach this network - there will be partial resource update
|
||||
log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s",
|
||||
@@ -221,31 +219,15 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
|
||||
return nil
|
||||
}
|
||||
|
||||
func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
|
||||
// This function tries to locate Compute by one of the following approaches:
|
||||
// - if compute_id is specified - locate by compute ID
|
||||
// - if compute_name is specified - locate by a combination of compute name and resource
|
||||
// group ID
|
||||
//
|
||||
// If succeeded, it returns non-empty string that contains JSON formatted facts about the
|
||||
// Compute as returned by compute/get API call.
|
||||
// Otherwise it returns empty string and meaningful error.
|
||||
//
|
||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||
// method for resource's Exists method.
|
||||
//
|
||||
|
||||
func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.RecordCompute, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
// make it possible to use "read" & "check presence" functions with compute ID set so
|
||||
// that Import of Compute resource is possible
|
||||
idSet := false
|
||||
theId, err := strconv.Atoi(d.Id())
|
||||
if err != nil || theId <= 0 {
|
||||
computeID, err := strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil || computeID <= 0 {
|
||||
computeId, argSet := d.GetOk("compute_id") // NB: compute_id is NOT present in computeResource schema!
|
||||
if argSet {
|
||||
theId = computeId.(int)
|
||||
computeID = uint64(computeId.(int))
|
||||
idSet = true
|
||||
}
|
||||
} else {
|
||||
@@ -254,11 +236,14 @@ func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m
|
||||
|
||||
if idSet {
|
||||
// compute ID is specified, try to get compute instance straight by this ID
|
||||
log.Debugf("utilityComputeCheckPresence: locating compute by its ID %d", theId)
|
||||
urlValues.Add("computeId", fmt.Sprintf("%d", theId))
|
||||
computeFacts, err := c.DecortAPICall(ctx, "POST", ComputeGetAPI, urlValues)
|
||||
log.Debugf("utilityComputeCheckPresence: locating compute by its ID %d", computeID)
|
||||
req := compute.GetRequest{
|
||||
ComputeID: computeID,
|
||||
}
|
||||
|
||||
computeFacts, err := c.CloudBroker().Compute().Get(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
return computeFacts, nil
|
||||
}
|
||||
@@ -267,44 +252,40 @@ func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m
|
||||
// and RG ID
|
||||
computeName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
return "", fmt.Errorf("Cannot locate compute instance if name is empty and no compute ID specified")
|
||||
return nil, fmt.Errorf("Cannot locate compute instance if name is empty and no compute ID specified")
|
||||
}
|
||||
|
||||
rgId, argSet := d.GetOk("rg_id")
|
||||
if !argSet {
|
||||
return "", fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string))
|
||||
return nil, fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string))
|
||||
}
|
||||
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgId))
|
||||
apiResp, err := c.DecortAPICall(ctx, "POST", RgListComputesAPI, urlValues)
|
||||
rgListComputesReq := rg.ListComputesRequest{
|
||||
RGID: uint64(rgId.(int)),
|
||||
}
|
||||
|
||||
computeList, err := c.CloudBroker().RG().ListComputes(ctx, rgListComputesReq)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("utilityComputeCheckPresence: ready to unmarshal string %s", apiResp)
|
||||
|
||||
computeList := RgListComputesResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &computeList)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// log.Printf("%#v", computeList)
|
||||
log.Debugf("utilityComputeCheckPresence: traversing decoded JSON of length %d", len(computeList))
|
||||
for index, item := range computeList {
|
||||
// need to match Compute by name, skip Computes with the same name in DESTROYED satus
|
||||
if item.Name == computeName.(string) && item.Status != "DESTROYED" {
|
||||
log.Debugf("utilityComputeCheckPresence: index %d, matched name %s", index, item.Name)
|
||||
// we found the Compute we need - now get detailed information via compute/get API
|
||||
cgetValues := &url.Values{}
|
||||
cgetValues.Add("computeId", fmt.Sprintf("%d", item.ID))
|
||||
apiResp, err = c.DecortAPICall(ctx, "POST", ComputeGetAPI, cgetValues)
|
||||
req := compute.GetRequest{
|
||||
ComputeID: item.ID,
|
||||
}
|
||||
|
||||
apiResp, err := c.CloudBroker().Compute().Get(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
return apiResp, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil // there should be no error if Compute does not exist
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package pcidevice
|
||||
|
||||
const pcideviceListAPI = "/restmachine/cloudbroker/pcidevice/list"
|
||||
const pcideviceDisableAPI = "/restmachine/cloudbroker/pcidevice/disable"
|
||||
const pcideviceEnableAPI = "/restmachine/cloudbroker/pcidevice/enable"
|
||||
const pcideviceCreateAPI = "/restmachine/cloudbroker/pcidevice/create"
|
||||
const pcideviceDeleteAPI = "/restmachine/cloudbroker/pcidevice/delete"
|
||||
@@ -49,11 +49,11 @@ func dataSourcePcideviceRead(ctx context.Context, d *schema.ResourceData, m inte
|
||||
|
||||
d.Set("ckey", pcidevice.CKey)
|
||||
d.Set("meta", flattens.FlattenMeta(pcidevice.Meta))
|
||||
d.Set("compute_id", pcidevice.Computeid)
|
||||
d.Set("compute_id", pcidevice.ComputeID)
|
||||
d.Set("description", pcidevice.Description)
|
||||
d.Set("guid", pcidevice.Guid)
|
||||
d.Set("guid", pcidevice.GUID)
|
||||
d.Set("hw_path", pcidevice.HwPath)
|
||||
d.Set("rg_id", pcidevice.RgID)
|
||||
d.Set("rg_id", pcidevice.RGID)
|
||||
d.Set("name", pcidevice.Name)
|
||||
d.Set("stack_id", pcidevice.StackID)
|
||||
d.Set("status", pcidevice.Status)
|
||||
|
||||
@@ -37,22 +37,23 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
)
|
||||
|
||||
func flattenPcideviceList(pl PcideviceList) []map[string]interface{} {
|
||||
func flattenPcideviceList(pl pcidevice.ListPCIDevices) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range pl {
|
||||
temp := map[string]interface{}{
|
||||
"ckey": item.CKey,
|
||||
"meta": flattens.FlattenMeta(item.Meta),
|
||||
"compute_id": item.Computeid,
|
||||
"compute_id": item.ComputeID,
|
||||
"description": item.Description,
|
||||
"guid": item.Guid,
|
||||
"guid": item.GUID,
|
||||
"hw_path": item.HwPath,
|
||||
"device_id": item.ID,
|
||||
"rg_id": item.RgID,
|
||||
"rg_id": item.RGID,
|
||||
"name": item.Name,
|
||||
"stack_id": item.StackID,
|
||||
"status": item.Status,
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package pcidevice
|
||||
|
||||
type Pcidevice struct {
|
||||
CKey string `json:"_ckey"`
|
||||
Meta []interface{} `json:"_meta"`
|
||||
Computeid int `json:"computeId"`
|
||||
Description string `json:"description"`
|
||||
Guid int `json:"guid"`
|
||||
HwPath string `json:"hwPath"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
RgID int `json:"rgId"`
|
||||
StackID int `json:"stackId"`
|
||||
Status string `json:"status"`
|
||||
SystemName string `json:"systemName"`
|
||||
}
|
||||
|
||||
type PcideviceList []Pcidevice
|
||||
@@ -33,45 +33,41 @@ package pcidevice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourcePcideviceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourcePcideviceCreate: called for pcidevice %s", d.Get("name").(string))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("hwPath", d.Get("hw_path").(string))
|
||||
urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int)))
|
||||
urlValues.Add("stackId", strconv.Itoa(d.Get("stack_id").(int)))
|
||||
|
||||
if description, ok := d.GetOk("description"); ok {
|
||||
urlValues.Add("description", description.(string))
|
||||
req := pcidevice.CreateRequest{
|
||||
Name: d.Get("name").(string),
|
||||
HWPath: d.Get("hw_path").(string),
|
||||
RGID: uint64(d.Get("rg_id").(int)),
|
||||
StackID: uint64(d.Get("stack_id").(int)),
|
||||
}
|
||||
|
||||
pcideviceId, err := c.DecortAPICall(ctx, "POST", pcideviceCreateAPI, urlValues)
|
||||
if description, ok := d.GetOk("description"); ok {
|
||||
req.Description = description.(string)
|
||||
}
|
||||
|
||||
pcideviceId, err := c.CloudBroker().PCIDevice().Create(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(pcideviceId)
|
||||
d.SetId(strconv.FormatUint(pcideviceId, 10))
|
||||
d.Set("device_id", pcideviceId)
|
||||
|
||||
diagnostics := resourcePcideviceRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
return diagnostics
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourcePcideviceRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourcePcideviceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -80,15 +76,14 @@ func resourcePcideviceRead(ctx context.Context, d *schema.ResourceData, m interf
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(pcidevice.ID))
|
||||
d.Set("ckey", pcidevice.CKey)
|
||||
d.Set("meta", flattens.FlattenMeta(pcidevice.Meta))
|
||||
d.Set("compute_id", pcidevice.Computeid)
|
||||
d.Set("compute_id", pcidevice.ComputeID)
|
||||
d.Set("description", pcidevice.Description)
|
||||
d.Set("guid", pcidevice.Guid)
|
||||
d.Set("guid", pcidevice.GUID)
|
||||
d.Set("hw_path", pcidevice.HwPath)
|
||||
d.Set("device_id", pcidevice.ID)
|
||||
d.Set("rg_id", pcidevice.RgID)
|
||||
d.Set("rg_id", pcidevice.RGID)
|
||||
d.Set("name", pcidevice.Name)
|
||||
d.Set("stack_id", pcidevice.StackID)
|
||||
d.Set("status", pcidevice.Status)
|
||||
@@ -101,11 +96,13 @@ func resourcePcideviceDelete(ctx context.Context, d *schema.ResourceData, m inte
|
||||
log.Debugf("resourcePcideviceDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("deviceId", d.Id())
|
||||
urlValues.Add("force", strconv.FormatBool(d.Get("force").(bool)))
|
||||
deviceID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req := pcidevice.DeleteRequest{
|
||||
DeviceID: deviceID,
|
||||
Force: d.Get("force").(bool),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", pcideviceDeleteAPI, urlValues)
|
||||
_, err := c.CloudBroker().PCIDevice().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -115,33 +112,33 @@ func resourcePcideviceDelete(ctx context.Context, d *schema.ResourceData, m inte
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourcePcideviceEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourcePcideviceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
if d.HasChange("enable") {
|
||||
state := d.Get("enable").(bool)
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
api := ""
|
||||
|
||||
urlValues.Add("deviceId", strconv.Itoa(d.Get("device_id").(int)))
|
||||
|
||||
if state {
|
||||
api = pcideviceEnableAPI
|
||||
req := pcidevice.EnableRequest{
|
||||
DeviceID: uint64(d.Get("device_id").(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().PCIDevice().Enable(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
api = pcideviceDisableAPI
|
||||
}
|
||||
req := pcidevice.DisableRequest{
|
||||
DeviceID: uint64(d.Get("device_id").(int)),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
_, err := c.CloudBroker().PCIDevice().Disable(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
diagnostics := resourcePcideviceRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
return diagnostics
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourcePcideviceRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourcePcideviceSchemaMake() map[string]*schema.Schema {
|
||||
@@ -225,7 +222,7 @@ func ResourcePcidevice() *schema.Resource {
|
||||
|
||||
CreateContext: resourcePcideviceCreate,
|
||||
ReadContext: resourcePcideviceRead,
|
||||
UpdateContext: resourcePcideviceEdit,
|
||||
UpdateContext: resourcePcideviceUpdate,
|
||||
DeleteContext: resourcePcideviceDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -36,19 +36,20 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice"
|
||||
)
|
||||
|
||||
func utilityPcideviceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Pcidevice, error) {
|
||||
func utilityPcideviceCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*pcidevice.ItemPCIDevice, error) {
|
||||
pcideviceList, err := utilityPcideviceListCheckPresence(ctx, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pcideviceId := 0
|
||||
var pcideviceId uint64
|
||||
if (d.Get("device_id").(int)) != 0 {
|
||||
pcideviceId = d.Get("device_id").(int)
|
||||
pcideviceId = uint64(d.Get("device_id").(int))
|
||||
} else {
|
||||
id, _ := strconv.Atoi(d.Id())
|
||||
id, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
pcideviceId = id
|
||||
}
|
||||
|
||||
|
||||
@@ -33,23 +33,15 @@ package pcidevice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityPcideviceListCheckPresence(ctx context.Context, m interface{}) (PcideviceList, error) {
|
||||
pcideviceList := PcideviceList{}
|
||||
func utilityPcideviceListCheckPresence(ctx context.Context, m interface{}) (pcidevice.ListPCIDevices, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
pcideviceListRaw, err := c.DecortAPICall(ctx, "POST", pcideviceListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(pcideviceListRaw), &pcideviceList)
|
||||
pcideviceList, err := c.CloudBroker().PCIDevice().List(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package pfw
|
||||
type PfwRecord struct {
|
||||
ID int `json:"id"`
|
||||
LocalIP string `json:"localIp"`
|
||||
LocalPort int `json:"localPort"`
|
||||
Protocol string `json:"protocol"`
|
||||
PublicPortEnd int `json:"publicPortEnd"`
|
||||
PublicPortStart int `json:"publicPortStart"`
|
||||
ComputeID int `json:"vmId"`
|
||||
}
|
||||
|
||||
type ComputePfwListResp []PfwRecord
|
||||
|
||||
|
||||
@@ -34,37 +34,36 @@ package pfw
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourcePfwCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
urlValues.Add("publicPortStart", strconv.Itoa(d.Get("public_port_start").(int)))
|
||||
urlValues.Add("localBasePort", strconv.Itoa(d.Get("local_base_port").(int)))
|
||||
urlValues.Add("proto", d.Get("proto").(string))
|
||||
req := compute.PFWAddRequest{}
|
||||
req.ComputeID = uint64(d.Get("compute_id").(int))
|
||||
req.PublicPortStart = uint64(d.Get("public_port_start").(int))
|
||||
req.LocalBasePort = uint64(d.Get("local_base_port").(int))
|
||||
req.Proto = d.Get("proto").(string)
|
||||
|
||||
if portEnd, ok := d.GetOk("public_port_end"); ok {
|
||||
urlValues.Add("publicPortEnd", strconv.Itoa(portEnd.(int)))
|
||||
req.PublicPortEnd = uint64(portEnd.(int))
|
||||
}
|
||||
|
||||
pfwId, err := c.DecortAPICall(ctx, "POST", ComputePfwAddAPI, urlValues)
|
||||
pfwId, err := c.CloudBroker().Compute().PFWAdd(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(fmt.Sprintf("%d-%s", d.Get("compute_id").(int), pfwId))
|
||||
d.SetId(fmt.Sprintf("%d-%d", d.Get("compute_id").(int), pfwId))
|
||||
|
||||
pfw, err := utilityPfwCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -88,7 +87,7 @@ func resourcePfwRead(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("compute_id", pfw.ComputeID)
|
||||
d.Set("compute_id", pfw.VMID)
|
||||
d.Set("public_port_start", pfw.PublicPortStart)
|
||||
d.Set("public_port_end", pfw.PublicPortEnd)
|
||||
d.Set("local_ip", pfw.LocalIP)
|
||||
@@ -110,15 +109,18 @@ func resourcePfwDelete(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
urlValues.Add("ruleId", strconv.Itoa(pfw.ID))
|
||||
req := compute.PFWDelRequest{
|
||||
ComputeID: uint64(d.Get("compute_id").(int)),
|
||||
RuleID: pfw.ID,
|
||||
}
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", ComputePfwDelAPI, urlValues)
|
||||
_, err = c.CloudBroker().Compute().PFWDel(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -33,27 +33,23 @@ package pfw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*PfwRecord, error) {
|
||||
func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemPFW, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
resp, err := c.DecortAPICall(ctx, "POST", ComputePfwListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := compute.PFWListRequest{
|
||||
ComputeID: uint64(d.Get("compute_id").(int)),
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
pfws, err := c.CloudBroker().Compute().PFWList(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idS := strings.Split(d.Id(), "-")[1]
|
||||
@@ -62,13 +58,8 @@ func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m inte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pfws []PfwRecord
|
||||
if err := json.Unmarshal([]byte(resp), &pfws); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, pfw := range pfws {
|
||||
if pfw.ID == id {
|
||||
if pfw.ID == uint64(id) {
|
||||
return &pfw, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,58 +33,42 @@ package rg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
// "net/url"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func flattenResgroup(d *schema.ResourceData, rg_facts string) error {
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourceRsgroupExists(...) method
|
||||
// log.Debugf("%s", rg_facts)
|
||||
log.Debugf("flattenResgroup: ready to decode response body from API")
|
||||
details := ResgroupGetResp{}
|
||||
err := json.Unmarshal([]byte(rg_facts), &details)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func flattenResgroup(d *schema.ResourceData, rgData *rg.RecordRG) error {
|
||||
log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d",
|
||||
details.Name, details.ID, details.AccountID)
|
||||
rgData.Name, rgData.ID, rgData.AccountID)
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", details.ID))
|
||||
d.Set("rg_id", details.ID)
|
||||
d.Set("name", details.Name)
|
||||
d.Set("account_name", details.AccountName)
|
||||
d.Set("account_id", details.AccountID)
|
||||
// d.Set("grid_id", details.GridID)
|
||||
d.Set("description", details.Desc)
|
||||
d.Set("status", details.Status)
|
||||
d.Set("def_net_type", details.DefaultNetType)
|
||||
d.Set("def_net_id", details.DefaultNetID)
|
||||
/*
|
||||
d.Set("vins", details.Vins)
|
||||
d.Set("computes", details.Computes)
|
||||
*/
|
||||
d.SetId(fmt.Sprintf("%d", rgData.ID))
|
||||
d.Set("rg_id", rgData.ID)
|
||||
d.Set("name", rgData.Name)
|
||||
d.Set("account_name", rgData.AccountName)
|
||||
d.Set("account_id", rgData.AccountID)
|
||||
// d.Set("grid_id", rgData.GridID)
|
||||
d.Set("description", rgData.Description)
|
||||
d.Set("status", rgData.Status)
|
||||
d.Set("def_net_type", rgData.DefNetType)
|
||||
d.Set("def_net_id", rgData.DefNetID)
|
||||
|
||||
log.Debugf("flattenResgroup: calling flattenQuota()")
|
||||
if err = d.Set("quota", parseQuota(details.Quota)); err != nil {
|
||||
return err
|
||||
}
|
||||
// log.Debugf("flattenResgroup: calling flattenQuota()")
|
||||
// if err := d.Set("quota", parseQuota(rgData.Resources)); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if rg_facts == "" {
|
||||
if rg_facts == nil {
|
||||
// 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
|
||||
d.SetId("") // ensure ID is empty in this case
|
||||
|
||||
@@ -37,24 +37,25 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenRgList(rgl ResgroupListResp) []map[string]interface{} {
|
||||
func flattenRgList(rgl rg.ListRG) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, rg := range rgl {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": rg.AccountID,
|
||||
"account_name": rg.AccountName,
|
||||
"acl": flattenRgAcl(rg.ACLs),
|
||||
"acl": flattenRgAcl(rg.ACL),
|
||||
"created_by": rg.CreatedBy,
|
||||
"created_time": rg.CreatedTime,
|
||||
"def_net_id": rg.DefaultNetID,
|
||||
"def_net_type": rg.DefaultNetType,
|
||||
"def_net_id": rg.DefNetID,
|
||||
"def_net_type": rg.DefNetType,
|
||||
"deleted_by": rg.DeletedBy,
|
||||
"deleted_time": rg.DeletedTime,
|
||||
"desc": rg.Decsription,
|
||||
"gid": rg.GridID,
|
||||
"desc": rg.Description,
|
||||
"gid": rg.GID,
|
||||
"guid": rg.GUID,
|
||||
"rg_id": rg.ID,
|
||||
"lock_status": rg.LockStatus,
|
||||
@@ -66,8 +67,8 @@ func flattenRgList(rgl ResgroupListResp) []map[string]interface{} {
|
||||
"status": rg.Status,
|
||||
"updated_by": rg.UpdatedBy,
|
||||
"updated_time": rg.UpdatedTime,
|
||||
"vins": rg.Vins,
|
||||
"vms": rg.Computes,
|
||||
"vins": rg.VINS,
|
||||
"vms": rg.VMs,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
@@ -75,31 +76,31 @@ func flattenRgList(rgl ResgroupListResp) []map[string]interface{} {
|
||||
|
||||
}
|
||||
|
||||
func flattenRgAcl(rgAcls []AccountAclRecord) []map[string]interface{} {
|
||||
func flattenRgAcl(rgAcls rg.ListACL) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, rgAcl := range rgAcls {
|
||||
temp := map[string]interface{}{
|
||||
"explicit": rgAcl.IsExplicit,
|
||||
"guid": rgAcl.Guid,
|
||||
"right": rgAcl.Rights,
|
||||
"explicit": rgAcl.Explicit,
|
||||
"guid": rgAcl.GUID,
|
||||
"right": rgAcl.Right,
|
||||
"status": rgAcl.Status,
|
||||
"type": rgAcl.Type,
|
||||
"user_group_id": rgAcl.UgroupID,
|
||||
"user_group_id": rgAcl.UserGroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} {
|
||||
func flattenRgResourceLimits(rl rg.ResourceLimits) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"cu_c": rl.CUC,
|
||||
"cu_d": rl.CUD,
|
||||
"cu_d": rl.CuD,
|
||||
"cu_i": rl.CUI,
|
||||
"cu_m": rl.CUM,
|
||||
"cu_np": rl.CUNP,
|
||||
"gpu_units": rl.GpuUnits,
|
||||
"gpu_units": rl.GPUUnits,
|
||||
}
|
||||
res = append(res, temp)
|
||||
|
||||
|
||||
@@ -126,12 +126,12 @@ type UserAclRecord struct {
|
||||
}
|
||||
|
||||
type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get
|
||||
Cpu int `json:"CU_C"` // CPU count in pcs
|
||||
Cpu float64 `json:"CU_C"` // CPU count in pcs
|
||||
Ram float64 `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
|
||||
Disk float64 `json:"CU_D"` // Disk capacity in GB
|
||||
ExtIPs float64 `json:"CU_I"` // Ext IPs count
|
||||
ExtTraffic float64 `json:"CU_NP"` // Ext network traffic
|
||||
GpuUnits float64 `json:"gpu_units"` // GPU count
|
||||
}
|
||||
|
||||
type ResourceRecord struct { // this is how actual usage is reported by /api/.../rg/get
|
||||
|
||||
@@ -33,6 +33,7 @@ package rg
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
)
|
||||
|
||||
func makeQuotaRecord(arg_list []interface{}) QuotaRecord {
|
||||
@@ -47,41 +48,41 @@ func makeQuotaRecord(arg_list []interface{}) QuotaRecord {
|
||||
subres_data := arg_list[0].(map[string]interface{})
|
||||
|
||||
if subres_data["cpu"].(int) > 0 {
|
||||
quota.Cpu = subres_data["cpu"].(int)
|
||||
quota.Cpu = subres_data["cpu"].(float64)
|
||||
}
|
||||
|
||||
if subres_data["disk"].(int) > 0 {
|
||||
quota.Disk = subres_data["disk"].(int) // Disk capacity ib GB
|
||||
quota.Disk = subres_data["disk"].(float64)
|
||||
}
|
||||
|
||||
if subres_data["ram"].(float64) > 0 {
|
||||
quota.Ram = subres_data["ram"].(float64) // RAM volume in MB, as float64!
|
||||
quota.Ram = subres_data["ram"].(float64)
|
||||
}
|
||||
|
||||
if subres_data["ext_traffic"].(int) > 0 {
|
||||
quota.ExtTraffic = subres_data["ext_traffic"].(int)
|
||||
quota.ExtTraffic = subres_data["ext_traffic"].(float64)
|
||||
}
|
||||
|
||||
if subres_data["ext_ips"].(int) > 0 {
|
||||
quota.ExtIPs = subres_data["ext_ips"].(int)
|
||||
quota.ExtIPs = subres_data["ext_ips"].(float64)
|
||||
}
|
||||
|
||||
if subres_data["gpu_units"].(int) > 0 {
|
||||
quota.GpuUnits = subres_data["gpu_units"].(int)
|
||||
quota.GpuUnits = subres_data["gpu_units"].(float64)
|
||||
}
|
||||
|
||||
return quota
|
||||
}
|
||||
|
||||
func parseQuota(quota QuotaRecord) []interface{} {
|
||||
func parseQuota(quota rg.ResourceLimits) []interface{} {
|
||||
quota_map := make(map[string]interface{})
|
||||
|
||||
quota_map["cpu"] = quota.Cpu
|
||||
quota_map["ram"] = quota.Ram // NB: this is float64, unlike the rest of values
|
||||
quota_map["disk"] = quota.Disk
|
||||
quota_map["ext_traffic"] = quota.ExtTraffic
|
||||
quota_map["ext_ips"] = quota.ExtIPs
|
||||
quota_map["gpu_units"] = quota.GpuUnits
|
||||
quota_map["cpu"] = quota.CUC
|
||||
quota_map["ram"] = quota.CUM
|
||||
quota_map["disk"] = quota.CuD
|
||||
quota_map["ext_traffic"] = quota.CUNP
|
||||
quota_map["ext_ips"] = quota.CUI
|
||||
quota_map["gpu_units"] = quota.GPUUnits
|
||||
|
||||
result := make([]interface{}, 1)
|
||||
result[0] = quota_map
|
||||
@@ -92,7 +93,7 @@ func parseQuota(quota QuotaRecord) []interface{} {
|
||||
func quotaRgSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Type: schema.TypeFloat,
|
||||
Optional: true,
|
||||
Default: -1,
|
||||
Description: "Limit on the total number of CPUs in this resource group.",
|
||||
@@ -106,28 +107,28 @@ func quotaRgSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
},
|
||||
|
||||
"disk": {
|
||||
Type: schema.TypeInt,
|
||||
Type: schema.TypeFloat,
|
||||
Optional: true,
|
||||
Default: -1,
|
||||
Description: "Limit on the total volume of storage resources in this resource group, specified in GB.",
|
||||
},
|
||||
|
||||
"ext_traffic": {
|
||||
Type: schema.TypeInt,
|
||||
Type: schema.TypeFloat,
|
||||
Optional: true,
|
||||
Default: -1,
|
||||
Description: "Limit on the total ingress network traffic for this resource group, specified in GB.",
|
||||
},
|
||||
|
||||
"ext_ips": {
|
||||
Type: schema.TypeInt,
|
||||
Type: schema.TypeFloat,
|
||||
Optional: true,
|
||||
Default: -1,
|
||||
Description: "Limit on the total number of external IP addresses this resource group can use.",
|
||||
},
|
||||
|
||||
"gpu_units": {
|
||||
Type: schema.TypeInt,
|
||||
Type: schema.TypeFloat,
|
||||
Optional: true,
|
||||
Default: -1,
|
||||
Description: "Limit on the total number of virtual GPUs this resource group can use.",
|
||||
|
||||
@@ -33,14 +33,14 @@ package rg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/location"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -48,32 +48,13 @@ import (
|
||||
)
|
||||
|
||||
func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
// First validate that we have all parameters required to create the 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
|
||||
|
||||
rg_name, arg_set := d.GetOk("name")
|
||||
if !arg_set {
|
||||
return diag.FromErr(fmt.Errorf("Cannot create new RG: missing name."))
|
||||
}
|
||||
|
||||
/* Current version of provider works with default grid id (same is true for disk resources)
|
||||
grid_id, arg_set := d.GetOk("grid_id")
|
||||
if !arg_set {
|
||||
return fmt.Errorf("Cannot create new RG %q in account ID %d: missing Grid ID.",
|
||||
rg_name.(string), validated_account_id)
|
||||
}
|
||||
if grid_id.(int) < 1 {
|
||||
grid_id = DefaultGridID
|
||||
}
|
||||
*/
|
||||
|
||||
// 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",
|
||||
rg_name.(string), d.Get("account_id").(int))
|
||||
|
||||
// quota settings are optional
|
||||
set_quota := false
|
||||
var quota_record QuotaRecord
|
||||
arg_value, arg_set := d.GetOk("quota")
|
||||
@@ -88,62 +69,57 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
c.GetDecortUsername(),
|
||||
rg_name.(string), d.Get("account_id").(int))
|
||||
|
||||
url_values := &url.Values{}
|
||||
url_values.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
||||
url_values.Add("name", rg_name.(string))
|
||||
url_values.Add("gid", fmt.Sprintf("%d", location.DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention
|
||||
url_values.Add("owner", c.GetDecortUsername())
|
||||
req := rg.CreateRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
Name: rg_name.(string),
|
||||
GID: uint64(location.DefaultGridID),
|
||||
Owner: c.GetDecortUsername(),
|
||||
}
|
||||
|
||||
// pass quota values as set
|
||||
if set_quota {
|
||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quota_record.Cpu))
|
||||
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quota_record.Disk))
|
||||
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quota_record.Ram)) // RAM quota is float; this may change in the future
|
||||
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quota_record.ExtTraffic))
|
||||
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quota_record.ExtIPs))
|
||||
req.MaxCPUCapacity = int64(quota_record.Cpu)
|
||||
req.MaxVDiskCapacity = int64(quota_record.Disk)
|
||||
req.MaxMemoryCapacity = int64(quota_record.Ram)
|
||||
req.MaxNetworkPeerTransfer = int64(quota_record.ExtTraffic)
|
||||
req.MaxNumPublicIP = int64(quota_record.ExtIPs)
|
||||
// url_values.Add("???", fmt.Sprintf("%d", quota_record.GpuUnits))
|
||||
}
|
||||
|
||||
// parse and handle network settings
|
||||
def_net_type, arg_set := d.GetOk("def_net_type")
|
||||
if arg_set {
|
||||
url_values.Add("def_net", def_net_type.(string)) // NOTE: in API default network type is set by "def_net" parameter
|
||||
req.DefNet = def_net_type.(string)
|
||||
}
|
||||
|
||||
ipcidr, arg_set := d.GetOk("ipcidr")
|
||||
if arg_set {
|
||||
url_values.Add("ipcidr", ipcidr.(string))
|
||||
req.IPCIDR = ipcidr.(string)
|
||||
}
|
||||
|
||||
ext_net_id, arg_set := d.GetOk("ext_net_id")
|
||||
if arg_set {
|
||||
url_values.Add("extNetId", fmt.Sprintf("%d", ext_net_id.(int)))
|
||||
req.ExtNetID = uint64(ext_net_id.(int))
|
||||
}
|
||||
|
||||
ext_ip, arg_set := d.GetOk("ext_ip")
|
||||
if arg_set {
|
||||
url_values.Add("extIp", ext_ip.(string))
|
||||
req.ExtIP = ext_ip.(string)
|
||||
}
|
||||
|
||||
api_resp, err := c.DecortAPICall(ctx, "POST", ResgroupCreateAPI, url_values)
|
||||
rgId, err := c.CloudBroker().RG().Create(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(api_resp) // rg/create API returns ID of the newly creted resource group on success
|
||||
// rg.ID, _ = strconv.Atoi(api_resp)
|
||||
d.SetId(strconv.FormatUint(rgId, 10))
|
||||
if !set_quota {
|
||||
resp, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
rg := ResgroupGetResp{}
|
||||
if err := json.Unmarshal([]byte(resp), &rg); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("quota", parseQuota(rg.Quota))
|
||||
d.Set("quota", parseQuota(resp.ResourceLimits))
|
||||
}
|
||||
|
||||
// re-read newly created RG to make sure schema contains complete and up to date set of specifications
|
||||
@@ -155,9 +131,7 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if rg_facts == "" {
|
||||
// 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
|
||||
if rg_facts == nil {
|
||||
d.SetId("") // ensure ID is empty
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -192,8 +166,10 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
do_general_update := false // will be true if general RG update is necessary (API rg/update)
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
url_values := &url.Values{}
|
||||
url_values.Add("rgId", d.Id())
|
||||
rgId, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req := rg.UpdateRequest{
|
||||
RGID: rgId,
|
||||
}
|
||||
|
||||
name_new, name_set := d.GetOk("name")
|
||||
if name_set {
|
||||
@@ -201,7 +177,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
name_old, _ := d.GetChange("name")
|
||||
if name_old.(string) != name_new.(string) {
|
||||
do_general_update = true
|
||||
url_values.Add("name", name_new.(string))
|
||||
req.Name = name_new.(string)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,31 +191,31 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
if quotarecord_new.Cpu != quotarecord_old.Cpu {
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu)
|
||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu))
|
||||
req.MaxCPUCapacity = int64(quotarecord_new.Cpu)
|
||||
}
|
||||
|
||||
if quotarecord_new.Disk != quotarecord_old.Disk {
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.Disk)
|
||||
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk))
|
||||
req.MaxVDiskCapacity = int64(quotarecord_new.Disk)
|
||||
}
|
||||
|
||||
if quotarecord_new.Ram != quotarecord_old.Ram { // NB: quota on RAM is stored as float32, in units of MB
|
||||
do_general_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))
|
||||
req.MaxMemoryCapacity = int64(quotarecord_new.Ram)
|
||||
}
|
||||
|
||||
if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic {
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic)
|
||||
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.ExtTraffic))
|
||||
req.MaxNetworkPeerTransfer = int64(quotarecord_new.ExtTraffic)
|
||||
}
|
||||
|
||||
if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs {
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs)
|
||||
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs))
|
||||
req.MaxNumPublicIP = int64(quotarecord_new.ExtIPs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,13 +225,13 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
desc_old, _ := d.GetChange("description")
|
||||
if desc_old.(string) != desc_new.(string) {
|
||||
do_general_update = true
|
||||
url_values.Add("desc", desc_new.(string))
|
||||
req.Description = desc_new.(string)
|
||||
}
|
||||
}
|
||||
|
||||
if do_general_update {
|
||||
log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG")
|
||||
_, err := c.DecortAPICall(ctx, "POST", ResgroupUpdateAPI, url_values)
|
||||
_, err := c.CloudBroker().RG().Update(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -267,29 +243,26 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
}
|
||||
|
||||
func resourceResgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
// 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 Computes & VINSes that existed in it
|
||||
log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d",
|
||||
d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if rg_facts == "" {
|
||||
if rg_facts == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
// the target RG does not exist - in this case according to Terraform best practice
|
||||
// we exit from Destroy method without error
|
||||
return nil
|
||||
}
|
||||
|
||||
url_values := &url.Values{}
|
||||
url_values.Add("rgId", d.Id())
|
||||
url_values.Add("force", "1")
|
||||
url_values.Add("permanently", "1")
|
||||
url_values.Add("reason", "Destroyed by DECORT Terraform provider")
|
||||
req := rg.DeleteRequest{
|
||||
RGID: rg_facts.ID,
|
||||
Force: true,
|
||||
Permanently: true,
|
||||
Reason: "Destroyed by DECORT Terraform provider",
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
_, err = c.DecortAPICall(ctx, "POST", ResgroupDeleteAPI, url_values)
|
||||
_, err = c.CloudBroker().RG().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
@@ -33,48 +33,25 @@ package rg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
// On success this function returns a string, as returned by API rg/get, which could be unmarshalled
|
||||
// into ResgroupGetResp structure
|
||||
func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
|
||||
// This function tries to locate resource group by one of the following algorithms depending
|
||||
// on the parameters passed:
|
||||
// - if resource group ID is specified -> by RG ID
|
||||
// - if resource group name is specifeid -> by RG name and either account ID or account name
|
||||
//
|
||||
// If succeeded, it returns non empty string that contains JSON formatted facts about the
|
||||
// resource group as returned by rg/get API call.
|
||||
// Otherwise it returns empty string and a 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
|
||||
// method for the Terraform resource Exists method.
|
||||
//
|
||||
|
||||
func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*rg.RecordRG, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
// make it possible to use "read" & "check presence" functions with RG ID set so
|
||||
// that Import of RG resource is possible
|
||||
idSet := false
|
||||
theId, err := strconv.Atoi(d.Id())
|
||||
theId, err := strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil || theId <= 0 {
|
||||
rgId, argSet := d.GetOk("rg_id")
|
||||
if argSet {
|
||||
theId = rgId.(int)
|
||||
theId = uint64(rgId.(int))
|
||||
idSet = true
|
||||
}
|
||||
} else {
|
||||
@@ -82,58 +59,50 @@ func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m
|
||||
}
|
||||
|
||||
if idSet {
|
||||
// go straight for the RG by its ID
|
||||
log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId)
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", theId))
|
||||
rgFacts, err := c.DecortAPICall(ctx, "POST", ResgroupGetAPI, urlValues)
|
||||
req := rg.GetRequest{
|
||||
RGID: theId,
|
||||
}
|
||||
|
||||
rgFacts, err := c.CloudBroker().RG().Get(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
return rgFacts, nil
|
||||
}
|
||||
|
||||
rgName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
// no RG ID and no RG name - we cannot locate resource group in this case
|
||||
return "", fmt.Errorf("Cannot check resource group presence if name is empty and no resource group ID specified")
|
||||
return nil, fmt.Errorf("Cannot check resource group presence if name is empty and no resource group ID specified")
|
||||
}
|
||||
|
||||
// Valid account ID is required to locate a resource group
|
||||
// obtain Account ID by account name - it should not be zero on success
|
||||
|
||||
urlValues.Add("includedeleted", "false")
|
||||
apiResp, err := c.DecortAPICall(ctx, "POST", ResgroupListAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
listReq := rg.ListRequest{
|
||||
IncludeDeleted: false,
|
||||
}
|
||||
// log.Debugf("%s", apiResp)
|
||||
log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", ResgroupListAPI)
|
||||
model := ResgroupListResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &model)
|
||||
model, err := c.CloudBroker().RG().List(ctx, listReq)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model))
|
||||
for index, item := range model {
|
||||
// match by RG name & account ID
|
||||
if item.Name == rgName.(string) && item.AccountID == d.Get("account_id").(int) {
|
||||
if item.Name == rgName.(string) && item.AccountID == uint64(d.Get("account_id").(int)) {
|
||||
log.Debugf("utilityResgroupCheckPresence: match RG name %s / ID %d, account ID %d at index %d",
|
||||
item.Name, item.ID, item.AccountID, index)
|
||||
|
||||
// not all required information is returned by rg/list API, so we need to initiate one more
|
||||
// call to rg/get to obtain extra data to complete Resource population.
|
||||
// Namely, we need resource quota settings
|
||||
reqValues := &url.Values{}
|
||||
reqValues.Add("rgId", fmt.Sprintf("%d", item.ID))
|
||||
apiResp, err := c.DecortAPICall(ctx, "POST", ResgroupGetAPI, reqValues)
|
||||
req := rg.GetRequest{
|
||||
RGID: item.ID,
|
||||
}
|
||||
|
||||
apiResp, err := c.CloudBroker().RG().Get(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return apiResp, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, d.Get("account_id").(int))
|
||||
return nil, fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, d.Get("account_id").(int))
|
||||
}
|
||||
|
||||
@@ -33,39 +33,30 @@ package rg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ResgroupListResp, error) {
|
||||
func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (rg.ListRG, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
rgList := ResgroupListResp{}
|
||||
req := rg.ListRequest{}
|
||||
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if includedeleted, ok := d.GetOk("includedeleted"); ok {
|
||||
urlValues.Add("includedeleted", strconv.FormatBool(includedeleted.(bool)))
|
||||
req.IncludeDeleted = includedeleted.(bool)
|
||||
}
|
||||
|
||||
log.Debugf("utilityRgListCheckPresence: load rg list")
|
||||
rgListRaw, err := c.DecortAPICall(ctx, "POST", ResgroupListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(rgListRaw), &rgList)
|
||||
rgList, err := c.CloudBroker().RG().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -50,13 +50,13 @@ func dataSourceSepRead(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
|
||||
d.Set("ckey", desSep.Ckey)
|
||||
d.Set("ckey", desSep.CKey)
|
||||
d.Set("meta", flattens.FlattenMeta(desSep.Meta))
|
||||
d.Set("consumed_by", desSep.ConsumedBy)
|
||||
d.Set("desc", desSep.Desc)
|
||||
d.Set("gid", desSep.Gid)
|
||||
d.Set("guid", desSep.Guid)
|
||||
d.Set("sep_id", desSep.Id)
|
||||
d.Set("desc", desSep.Description)
|
||||
d.Set("gid", desSep.GID)
|
||||
d.Set("guid", desSep.GUID)
|
||||
d.Set("sep_id", desSep.ID)
|
||||
d.Set("milestones", desSep.Milestones)
|
||||
d.Set("name", desSep.Name)
|
||||
d.Set("obj_status", desSep.ObjStatus)
|
||||
|
||||
@@ -37,9 +37,11 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
// TODO: how to marshal byPool????
|
||||
func dataSourceSepConsumptionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
sepCons, err := utilitySepConsumptionCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -50,7 +52,7 @@ func dataSourceSepConsumptionRead(ctx context.Context, d *schema.ResourceData, m
|
||||
|
||||
d.Set("type", sepCons.Type)
|
||||
d.Set("total", flattenSepConsumption(sepCons.Total))
|
||||
d.Set("by_pool", flattenSepConsumptionPools(sepCons.ByPool))
|
||||
// d.Set("by_pool", flattenSepConsumptionPools(sepCons.ByPool))
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -72,7 +74,7 @@ func flattenSepConsumptionPools(mp map[string]SepConsumptionInd) []map[string]in
|
||||
return sh
|
||||
}
|
||||
|
||||
func flattenSepConsumption(sc SepConsumptionTotal) []map[string]interface{} {
|
||||
func flattenSepConsumption(sc sep.Total) []map[string]interface{} {
|
||||
sh := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"capacity_limit": sc.CapacityLimit,
|
||||
|
||||
@@ -38,22 +38,23 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
)
|
||||
|
||||
func flattenSepList(sl SepList) []map[string]interface{} {
|
||||
func flattenSepList(sl sep.ListSEP) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range sl {
|
||||
data, _ := json.Marshal(item.Config)
|
||||
temp := map[string]interface{}{
|
||||
"ckey": item.Ckey,
|
||||
"ckey": item.CKey,
|
||||
"meta": flattens.FlattenMeta(item.Meta),
|
||||
"consumed_by": item.ConsumedBy,
|
||||
"desc": item.Desc,
|
||||
"gid": item.Gid,
|
||||
"guid": item.Guid,
|
||||
"sep_id": item.Id,
|
||||
"desc": item.Description,
|
||||
"gid": item.GID,
|
||||
"guid": item.GUID,
|
||||
"sep_id": item.ID,
|
||||
"milestones": item.Milestones,
|
||||
"name": item.Name,
|
||||
"obj_status": item.ObjStatus,
|
||||
|
||||
@@ -34,78 +34,60 @@ package sep
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceSepCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceSepCreate: called for sep %s", d.Get("name").(string))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := sep.CreateRequest{}
|
||||
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
|
||||
urlValues.Add("sep_type", d.Get("type").(string))
|
||||
req.Name = d.Get("name").(string)
|
||||
req.GID = uint64(d.Get("gid").(int))
|
||||
req.SEPType = d.Get("type").(string)
|
||||
|
||||
if desc, ok := d.GetOk("desc"); ok {
|
||||
urlValues.Add("description", desc.(string))
|
||||
req.Description = desc.(string)
|
||||
}
|
||||
if configString, ok := d.GetOk("config"); ok {
|
||||
urlValues.Add("config", configString.(string))
|
||||
req.Config = configString.(string)
|
||||
}
|
||||
if enable, ok := d.GetOk("enable"); ok {
|
||||
urlValues.Add("enable", strconv.FormatBool(enable.(bool)))
|
||||
req.Enable = enable.(bool)
|
||||
}
|
||||
|
||||
tstr := d.Get("consumed_by").([]interface{})
|
||||
temp := ""
|
||||
l := len(tstr)
|
||||
for i, str := range tstr {
|
||||
s := "\"" + str.(string) + "\""
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
var consumedNIDs []uint64
|
||||
for _, item := range d.Get("consumed_by").([]interface{}) {
|
||||
consumedNIDs = append(consumedNIDs, uint64(item.(int)))
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("consumer_nids", temp)
|
||||
|
||||
tstr = d.Get("provided_by").([]interface{})
|
||||
temp = ""
|
||||
l = len(tstr)
|
||||
for i, str := range tstr {
|
||||
s := "\"" + str.(string) + "\""
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
req.ConsumerNIDs = consumedNIDs
|
||||
|
||||
var providerNIDs []uint64
|
||||
for _, item := range d.Get("provided_by").([]interface{}) {
|
||||
providerNIDs = append(providerNIDs, uint64(item.(int)))
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("provider_nids", temp)
|
||||
|
||||
sepId, err := c.DecortAPICall(ctx, "POST", sepCreateAPI, urlValues)
|
||||
req.ProviderNIDs = providerNIDs
|
||||
|
||||
sepId, err := c.CloudBroker().SEP().Create(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(sepId)
|
||||
d.SetId(strconv.FormatUint(sepId, 10))
|
||||
d.Set("sep_id", sepId)
|
||||
|
||||
diagnostics := resourceSepRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
return diagnostics
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourceSepRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceSepRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -117,13 +99,13 @@ func resourceSepRead(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("ckey", sep.Ckey)
|
||||
d.Set("ckey", sep.CKey)
|
||||
d.Set("meta", flattens.FlattenMeta(sep.Meta))
|
||||
d.Set("consumed_by", sep.ConsumedBy)
|
||||
d.Set("desc", sep.Desc)
|
||||
d.Set("gid", sep.Gid)
|
||||
d.Set("guid", sep.Guid)
|
||||
d.Set("sep_id", sep.Id)
|
||||
d.Set("desc", sep.Description)
|
||||
d.Set("gid", sep.GID)
|
||||
d.Set("guid", sep.GUID)
|
||||
d.Set("sep_id", sep.ID)
|
||||
d.Set("milestones", sep.Milestones)
|
||||
d.Set("name", sep.Name)
|
||||
d.Set("obj_status", sep.ObjStatus)
|
||||
@@ -148,78 +130,91 @@ func resourceSepDelete(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
req := sep.DeleteRequest{
|
||||
SEPID: sepDes.ID,
|
||||
}
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", sepDeleteAPI, urlValues)
|
||||
_, err = c.CloudBroker().SEP().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceSepUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceSepEdit: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
if d.HasChange("decommission") {
|
||||
decommission := d.Get("decommission").(bool)
|
||||
if decommission {
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
urlValues.Add("clear_physically", strconv.FormatBool(d.Get("clear_physically").(bool)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", sepDecommissionAPI, urlValues)
|
||||
req := sep.DecommissionRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
ClearPhisically: d.Get("clear_physically").(bool),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().SEP().Decommission(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
if d.HasChange("upd_capacity_limit") {
|
||||
updCapacityLimit := d.Get("upd_capacity_limit").(bool)
|
||||
if updCapacityLimit {
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", sepUpdateCapacityLimitAPI, urlValues)
|
||||
req := sep.UpdateCapacityLimitRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().SEP().UpdateCapacityLimit(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
if d.HasChange("config") {
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
urlValues.Add("config", d.Get("config").(string))
|
||||
_, err := c.DecortAPICall(ctx, "POST", sepConfigValidateAPI, urlValues)
|
||||
validateReq := sep.ConfigValidateRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
Config: d.Get("config").(string),
|
||||
}
|
||||
|
||||
insertReq := sep.ConfigInsertRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
Config: d.Get("config").(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().SEP().ConfigValidate(ctx, validateReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
_, err = c.DecortAPICall(ctx, "POST", sepConfigInsertAPI, urlValues)
|
||||
_, err = c.CloudBroker().SEP().ConfigInsert(ctx, insertReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
if d.HasChange("field_edit") {
|
||||
fieldConfig := d.Get("field_edit").([]interface{})
|
||||
field := fieldConfig[0].(map[string]interface{})
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
urlValues.Add("field_name", field["field_name"].(string))
|
||||
urlValues.Add("field_value", field["field_value"].(string))
|
||||
urlValues.Add("field_type", field["field_type"].(string))
|
||||
req := sep.ConfigFieldEditRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
FieldName: field["field_name"].(string),
|
||||
FieldValue: field["field_value"].(string),
|
||||
FieldType: field["field_type"].(string),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", sepConfigFieldEditAPI, urlValues)
|
||||
_, err := c.CloudBroker().SEP().ConfigFieldEdit(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
if d.HasChange("enable") {
|
||||
err := resourceSepChangeEnabled(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -227,7 +222,6 @@ func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
}
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
if d.HasChange("consumed_by") {
|
||||
err := resourceSepUpdateNodes(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -235,7 +229,6 @@ func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
}
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
if d.HasChange("provided_by") {
|
||||
err := resourceSepUpdateProviders(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -243,7 +236,6 @@ func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
}
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
if diagnostics := resourceSepRead(ctx, d, m); diagnostics != nil {
|
||||
return diagnostics
|
||||
}
|
||||
@@ -252,42 +244,48 @@ func resourceSepEdit(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
}
|
||||
|
||||
func resourceSepChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
var api string
|
||||
sepID := uint64(d.Get("sep_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
if d.Get("enable").(bool) {
|
||||
api = sepEnableAPI
|
||||
req := sep.EnableRequest{
|
||||
SEPID: sepID,
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().SEP().Enable(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
api = sepDisableAPI
|
||||
}
|
||||
resp, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := strconv.ParseBool(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !res {
|
||||
return errors.New("Cannot enable/disable")
|
||||
req := sep.DisableRequest{
|
||||
SEPID: sepID,
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().SEP().Disable(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceSepUpdateNodes(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceSepUpdateNodes: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
delReq := sep.DelConsumerNodesRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
}
|
||||
|
||||
addReq := sep.AddConsumerNodesRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
}
|
||||
|
||||
toDel := false
|
||||
|
||||
t1, t2 := d.GetChange("consumed_by")
|
||||
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
|
||||
consumedIds := make([]interface{}, 0)
|
||||
temp := ""
|
||||
api := ""
|
||||
|
||||
if d1, d2 := t1.([]interface{}), t2.([]interface{}); len(d1) > len(d2) {
|
||||
for _, n := range d2 {
|
||||
@@ -295,25 +293,30 @@ func resourceSepUpdateNodes(ctx context.Context, d *schema.ResourceData, m inter
|
||||
consumedIds = append(consumedIds, n)
|
||||
}
|
||||
}
|
||||
api = sepDelConsumerNodesAPI
|
||||
toDel = true
|
||||
} else {
|
||||
consumedIds = d.Get("consumed_by").([]interface{})
|
||||
api = sepAddConsumerNodesAPI
|
||||
}
|
||||
|
||||
l := len(consumedIds)
|
||||
for i, consumedId := range consumedIds {
|
||||
s := strconv.Itoa(consumedId.(int))
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
var consumerNIDs []uint64
|
||||
for _, consumedId := range consumedIds {
|
||||
consumerNIDs = append(consumerNIDs, uint64(consumedId.(int)))
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("consumer_nids", temp)
|
||||
_, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
if toDel {
|
||||
delReq.ConsumerNIDs = consumerNIDs
|
||||
|
||||
_, err := c.CloudBroker().SEP().DelConsumerNodes(ctx, delReq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
addReq.ConsumerNIDs = consumerNIDs
|
||||
|
||||
_, err := c.CloudBroker().SEP().AddConsumerNodes(ctx, addReq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -331,21 +334,17 @@ func findElInt(sl []interface{}, el interface{}) bool {
|
||||
func resourceSepUpdateProviders(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceSepUpdateProviders: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
providerIds := d.Get("provided_by").([]interface{})
|
||||
temp := ""
|
||||
l := len(providerIds)
|
||||
for i, providerId := range providerIds {
|
||||
s := strconv.Itoa(providerId.(int))
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
req := sep.AddProviderNodesRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("provider_nids", temp)
|
||||
_, err := c.DecortAPICall(ctx, "POST", sepAddProviderNodesAPI, urlValues)
|
||||
|
||||
var providerNIDs []uint64
|
||||
for _, item := range d.Get("provided_by").([]interface{}) {
|
||||
providerNIDs = append(providerNIDs, uint64(item.(int)))
|
||||
}
|
||||
req.ProviderNIDs = providerNIDs
|
||||
|
||||
_, err := c.CloudBroker().SEP().AddProviderNodes(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -488,7 +487,7 @@ func ResourceSep() *schema.Resource {
|
||||
|
||||
CreateContext: resourceSepCreate,
|
||||
ReadContext: resourceSepRead,
|
||||
UpdateContext: resourceSepEdit,
|
||||
UpdateContext: resourceSepUpdate,
|
||||
DeleteContext: resourceSepDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -34,15 +34,14 @@ package sep
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceSepConfigCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -100,35 +99,43 @@ func resourceSepConfigExists(ctx context.Context, d *schema.ResourceData, m inte
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourceSepConfigEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceSepConfigUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceSepConfigEdit: called for sep id: %d", d.Get("sep_id").(int))
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
if d.HasChange("config") {
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
urlValues.Add("config", d.Get("config").(string))
|
||||
_, err := c.DecortAPICall(ctx, "POST", sepConfigValidateAPI, urlValues)
|
||||
validateReq := sep.ConfigValidateRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
Config: d.Get("config").(string),
|
||||
}
|
||||
insertReq := sep.ConfigInsertRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
Config: d.Get("config").(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().SEP().ConfigValidate(ctx, validateReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
_, err = c.DecortAPICall(ctx, "POST", sepConfigInsertAPI, urlValues)
|
||||
|
||||
_, err = c.CloudBroker().SEP().ConfigInsert(ctx, insertReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
if d.HasChange("field_edit") {
|
||||
fieldConfig := d.Get("field_edit").([]interface{})
|
||||
field := fieldConfig[0].(map[string]interface{})
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
urlValues.Add("field_name", field["field_name"].(string))
|
||||
urlValues.Add("field_value", field["field_value"].(string))
|
||||
urlValues.Add("field_type", field["field_type"].(string))
|
||||
req := sep.ConfigFieldEditRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
FieldName: field["field_name"].(string),
|
||||
FieldValue: field["field_value"].(string),
|
||||
FieldType: field["field_type"].(string),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", sepConfigFieldEditAPI, urlValues)
|
||||
_, err := c.CloudBroker().SEP().ConfigFieldEdit(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -184,7 +191,7 @@ func ResourceSepConfig() *schema.Resource {
|
||||
|
||||
CreateContext: resourceSepConfigCreate,
|
||||
ReadContext: resourceSepConfigRead,
|
||||
UpdateContext: resourceSepConfigEdit,
|
||||
UpdateContext: resourceSepConfigUpdate,
|
||||
DeleteContext: resourceSepConfigDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -33,35 +33,28 @@ package sep
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilitySepCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Sep, error) {
|
||||
func utilitySepCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordSEP, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
sep := &Sep{}
|
||||
req := sep.GetRequest{}
|
||||
|
||||
if d.Get("sep_id").(int) == 0 {
|
||||
urlValues.Add("sep_id", d.Id())
|
||||
id, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req.SEPID = id
|
||||
} else {
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
req.SEPID = uint64(d.Get("sep_id").(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilitySepCheckPresence: load sep")
|
||||
sepRaw, err := c.DecortAPICall(ctx, "POST", sepGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(sepRaw), sep)
|
||||
sep, err := c.CloudBroker().SEP().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,31 +33,22 @@ package sep
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilitySepConfigCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SepConfig, error) {
|
||||
func utilitySepConfigCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.SEPConfig, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
sepConfig := SepConfig{}
|
||||
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
|
||||
log.Debugf("utilitySepConfigCheckPresence: load sep config")
|
||||
sepConfigRaw, err := c.DecortAPICall(ctx, "POST", sepGetConfigAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := sep.GetConfigRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(sepConfigRaw), &sepConfig)
|
||||
log.Debugf("utilitySepConfigCheckPresence: load sep config")
|
||||
sepConfig, err := c.CloudBroker().SEP().GetConfig(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,28 +33,19 @@ package sep
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilitySepConsumptionCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*SepConsumption, error) {
|
||||
func utilitySepConsumptionCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordConsumption, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
sepCons := &SepConsumption{}
|
||||
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
|
||||
sepConsRaw, err := c.DecortAPICall(ctx, "POST", sepConsumptionAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := sep.ConsumptionRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(sepConsRaw), sepCons)
|
||||
sepCons, err := c.CloudBroker().SEP().Consumption(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,35 +33,26 @@ package sep
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilitySepDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]int, error) {
|
||||
func utilitySepDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) ([]uint64, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
sepDiskList := SepDiskList{}
|
||||
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
req := sep.DiskListRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
}
|
||||
|
||||
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||
urlValues.Add("pool_name", poolName.(string))
|
||||
req.PoolName = poolName.(string)
|
||||
}
|
||||
|
||||
log.Debugf("utilitySepDiskListCheckPresence: load sep")
|
||||
sepDiskListRaw, err := c.DecortAPICall(ctx, "POST", sepDiskListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(sepDiskListRaw), &sepDiskList)
|
||||
sepDiskList, err := c.CloudBroker().SEP().DiskList(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,35 +33,27 @@ package sep
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilitySepListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SepList, error) {
|
||||
sepList := SepList{}
|
||||
func utilitySepListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (sep.ListSEP, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := sep.ListRequest{}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilitySepListCheckPresence: load image list")
|
||||
sepListRaw, err := c.DecortAPICall(ctx, "POST", sepListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(sepListRaw), &sepList)
|
||||
sepList, err := c.CloudBroker().SEP().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -33,32 +33,23 @@ package sep
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/sep"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilitySepPoolCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SepPool, error) {
|
||||
func utilitySepPoolCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*sep.RecordPool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
sepPool := SepPool{}
|
||||
|
||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
||||
urlValues.Add("pool_name", d.Get("pool_name").(string))
|
||||
|
||||
log.Debugf("utilitySepDesPoolCheckPresence: load sep")
|
||||
sepPoolRaw, err := c.DecortAPICall(ctx, "POST", sepGetPoolAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req := sep.GetPoolRequest{
|
||||
SEPID: uint64(d.Get("sep_id").(int)),
|
||||
PoolName: d.Get("pool_name").(string),
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(sepPoolRaw), &sepPool)
|
||||
log.Debugf("utilitySepDesPoolCheckPresence: load sep")
|
||||
sepPool, err := c.CloudBroker().SEP().GetPool(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -37,15 +37,16 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenSnapshotList(gl SnapshotList) []map[string]interface{} {
|
||||
func flattenSnapshotList(gl compute.ListSnapshots) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range gl {
|
||||
temp := map[string]interface{}{
|
||||
"label": item.Label,
|
||||
"guid": item.Guid,
|
||||
"guid": item.GUID,
|
||||
"disks": item.Disks,
|
||||
"timestamp": item.Timestamp,
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package snapshot
|
||||
|
||||
type Snapshot struct {
|
||||
Disks []int `json:"disks"`
|
||||
Guid string `json:"guid"`
|
||||
Label string `json:"label"`
|
||||
Timestamp uint64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type SnapshotList []Snapshot
|
||||
@@ -33,26 +33,26 @@ package snapshot
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceSnapshotCreate: called for snapshot %s", d.Get("label").(string))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("label", d.Get("label").(string))
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
req := compute.SnapshotCreateRequest{
|
||||
Label: d.Get("label").(string),
|
||||
ComputeID: uint64(d.Get("compute_id").(int)),
|
||||
}
|
||||
|
||||
snapshotId, err := c.DecortAPICall(ctx, "POST", snapshotCreateAPI, urlValues)
|
||||
snapshotId, err := c.CloudBroker().Compute().SnapshotCreate(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -62,12 +62,7 @@ func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
d.SetId(snapshotId)
|
||||
d.Set("guid", snapshotId)
|
||||
|
||||
diagnostics := resourceSnapshotRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
return diagnostics
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourceSnapshotRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -77,7 +72,7 @@ func resourceSnapshotRead(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
}
|
||||
|
||||
d.Set("timestamp", snapshot.Timestamp)
|
||||
d.Set("guid", snapshot.Guid)
|
||||
d.Set("guid", snapshot.GUID)
|
||||
d.Set("disks", snapshot.Disks)
|
||||
d.Set("label", snapshot.Label)
|
||||
|
||||
@@ -88,20 +83,22 @@ func resourceSnapshotDelete(ctx context.Context, d *schema.ResourceData, m inter
|
||||
log.Debugf("resourceSnapshotDelete: called for %s, id: %s", d.Get("label").(string), d.Id())
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
urlValues.Add("label", d.Get("label").(string))
|
||||
req := compute.SnapshotDeleteRequest{
|
||||
ComputeID: uint64(d.Get("compute_id").(int)),
|
||||
Label: d.Get("label").(string),
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", snapshotDeleteAPI, urlValues)
|
||||
_, err := c.CloudBroker().Compute().SnapshotDelete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceSnapshotEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
if d.HasChange("rollback") {
|
||||
if d.Get("rollback").(bool) {
|
||||
err := resourceSnapshotRollback(ctx, d, m)
|
||||
@@ -116,12 +113,12 @@ func resourceSnapshotEdit(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
|
||||
func resourceSnapshotRollback(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := compute.SnapshotRollbackRequest{
|
||||
ComputeID: uint64(d.Get("compute_id").(int)),
|
||||
Label: d.Get("label").(string),
|
||||
}
|
||||
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
urlValues.Add("label", d.Get("label").(string))
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", snapshotRollbackAPI, urlValues)
|
||||
_, err := c.CloudBroker().Compute().SnapshotRollback(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -174,7 +171,7 @@ func ResourceSnapshot() *schema.Resource {
|
||||
|
||||
CreateContext: resourceSnapshotCreate,
|
||||
ReadContext: resourceSnapshotRead,
|
||||
UpdateContext: resourceSnapshotEdit,
|
||||
UpdateContext: resourceSnapshotUpdate,
|
||||
DeleteContext: resourceSnapshotDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -36,9 +36,10 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
)
|
||||
|
||||
func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Snapshot, error) {
|
||||
func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*compute.ItemSnapshot, error) {
|
||||
snapShotList, err := utilitySnapshotListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -53,7 +54,7 @@ func utilitySnapshotCheckPresence(ctx context.Context, d *schema.ResourceData, m
|
||||
}
|
||||
|
||||
for _, s := range snapShotList {
|
||||
if s.Guid == findId {
|
||||
if s.GUID == findId {
|
||||
return &s, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,33 +33,22 @@ package snapshot
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilitySnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (SnapshotList, error) {
|
||||
func utilitySnapshotListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (compute.ListSnapshots, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
req := compute.SnapshotListRequest{
|
||||
ComputeID: uint64(d.Get("compute_id").(int)),
|
||||
}
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", snapshotListAPI, urlValues)
|
||||
snapshotList, err := c.CloudBroker().Compute().SnapshotList(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
snapshotList := SnapshotList{}
|
||||
if err := json.Unmarshal([]byte(resp), &snapshotList); err != nil {
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return snapshotList, nil
|
||||
}
|
||||
|
||||
@@ -46,16 +46,16 @@ func dataSourceVGPURead(ctx context.Context, d *schema.ResourceData, m interface
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(vgpu.ID))
|
||||
d.SetId(strconv.FormatUint(vgpu.ID, 10))
|
||||
d.Set("vgpu_id", vgpu.ID)
|
||||
d.Set("account_id", vgpu.AccountID)
|
||||
d.Set("mode", vgpu.Mode)
|
||||
d.Set("pgpu", vgpu.PgpuID)
|
||||
d.Set("pgpu", vgpu.PGPUID)
|
||||
d.Set("profile_id", vgpu.ProfileID)
|
||||
d.Set("ram", vgpu.RAM)
|
||||
d.Set("status", vgpu.Status)
|
||||
d.Set("type", vgpu.Type)
|
||||
d.Set("vm_id", vgpu.VmID)
|
||||
d.Set("vm_id", vgpu.VMID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package vgpu
|
||||
|
||||
type VGPU struct {
|
||||
AccountID int `json:"accountId"`
|
||||
ID int `json:"id"`
|
||||
Mode string `json:"mode"`
|
||||
PgpuID int `json:"pgpuid"`
|
||||
ProfileID int `json:"profileId"`
|
||||
RAM int `json:"ram"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
VmID int `json:"vmid"`
|
||||
}
|
||||
@@ -33,47 +33,38 @@ package vgpu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vgpu"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityVGPUCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*VGPU, error) {
|
||||
func utilityVGPUCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vgpu.ItemVGPU, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("size", "50")
|
||||
req := vgpu.ListRequest{
|
||||
Size: 50,
|
||||
}
|
||||
|
||||
var vgpuId int
|
||||
var vgpuId uint64
|
||||
var err error
|
||||
|
||||
if vId, ok := d.GetOk("vgpu_id"); ok {
|
||||
vgpuId = vId.(int)
|
||||
vgpuId = uint64(vId.(int))
|
||||
} else {
|
||||
vgpuId, err = strconv.Atoi(d.Id())
|
||||
vgpuId, err = strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for page := 1; ; page++ {
|
||||
urlValues.Set("page", strconv.Itoa(page))
|
||||
resp, err := c.DecortAPICall(ctx, "POST", vgpuListAPI, urlValues)
|
||||
req.Page = uint64(page)
|
||||
vgpus, err := c.CloudBroker().VGPU().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "[]" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var vgpus []VGPU
|
||||
if err := json.Unmarshal([]byte(resp), &vgpus); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, vgpu := range vgpus {
|
||||
if vgpu.ID == vgpuId {
|
||||
return &vgpu, nil
|
||||
|
||||
@@ -33,11 +33,12 @@ package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
|
||||
// "net/url"
|
||||
|
||||
@@ -46,44 +47,32 @@ import (
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
// vins_facts is a response string from API vins/get
|
||||
func flattenVins(d *schema.ResourceData, vins_facts string) diag.Diagnostics {
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourceVinsExists(...) method
|
||||
// log.Debugf("flattenVins: ready to decode response body from API %s", vins_facts)
|
||||
vinsRecord := VinsRecord{}
|
||||
err := json.Unmarshal([]byte(vins_facts), &vinsRecord)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
func flattenVins(d *schema.ResourceData, vinsRecord *vins.RecordVINS) diag.Diagnostics {
|
||||
log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d",
|
||||
vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID)
|
||||
vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RGID)
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", vinsRecord.ID))
|
||||
d.Set("name", vinsRecord.Name)
|
||||
d.Set("account_id", vinsRecord.AccountID)
|
||||
d.Set("account_name", vinsRecord.AccountName)
|
||||
d.Set("rg_id", vinsRecord.RgID)
|
||||
d.Set("description", vinsRecord.Desc)
|
||||
d.Set("ipcidr", vinsRecord.IPCidr)
|
||||
// d.Set("account_name", vinsRecord.AccountName)
|
||||
d.Set("rg_id", vinsRecord.RGID)
|
||||
d.Set("description", vinsRecord.Description)
|
||||
d.Set("ipcidr", vinsRecord.Network)
|
||||
|
||||
noExtNetConnection := true
|
||||
for _, value := range vinsRecord.VNFs {
|
||||
if value.Type == "GW" {
|
||||
log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", value.ID, vinsRecord.ID)
|
||||
extNetID, idOk := value.Config["ext_net_id"] // NOTE: unknown numbers are unmarshalled to float64. This is by design!
|
||||
extNetIP, ipOk := value.Config["ext_net_ip"]
|
||||
if idOk && ipOk {
|
||||
log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", int(extNetID.(float64)), extNetIP.(string))
|
||||
d.Set("ext_ip_addr", extNetIP.(string))
|
||||
d.Set("ext_net_id", int(extNetID.(float64)))
|
||||
} else {
|
||||
return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.")
|
||||
}
|
||||
noExtNetConnection = false
|
||||
break
|
||||
gw := vinsRecord.VNFs.GW
|
||||
if !reflect.ValueOf(gw).IsZero() {
|
||||
log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", gw.ID, vinsRecord.ID)
|
||||
extNetID := gw.Config.ExtNetID
|
||||
extNetIP := gw.Config.ExtNetIP
|
||||
if extNetID != 0 && extNetIP != "" {
|
||||
log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", extNetID, extNetIP)
|
||||
d.Set("ext_ip_addr", extNetIP)
|
||||
d.Set("ext_net_id", extNetID)
|
||||
} else {
|
||||
return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.")
|
||||
}
|
||||
noExtNetConnection = false
|
||||
}
|
||||
|
||||
if noExtNetConnection {
|
||||
@@ -98,10 +87,8 @@ func flattenVins(d *schema.ResourceData, vins_facts string) diag.Diagnostics {
|
||||
|
||||
func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if vinsFacts == "" {
|
||||
// if empty string is returned from utilityVinsCheckPresence then there is no
|
||||
// such ViNS and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty in this case
|
||||
if vinsFacts == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,14 +37,15 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenVinsList(vl VinsList) []map[string]interface{} {
|
||||
func flattenVinsList(vl vins.ListVINS) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, v := range vl {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": v.AccountId,
|
||||
"account_id": v.AccountID,
|
||||
"account_name": v.AccountName,
|
||||
"created_by": v.CreatedBy,
|
||||
"created_time": v.CreatedTime,
|
||||
@@ -59,7 +60,7 @@ func flattenVinsList(vl VinsList) []map[string]interface{} {
|
||||
"status": v.Status,
|
||||
"updated_by": v.UpdatedBy,
|
||||
"updated_time": v.UpdatedTime,
|
||||
"vxlan_id": v.VXLanID,
|
||||
"vxlan_id": v.VXLANID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package vins
|
||||
|
||||
type Vins struct {
|
||||
AccountId int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
CreatedTime int `json:"createdTime"`
|
||||
DeletedBy string `json:"deletedBy"`
|
||||
DeletedTime int `json:"deletedTime"`
|
||||
ExternalIP string `json:"externalIP"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Network string `json:"network"`
|
||||
RGID int `json:"rgId"`
|
||||
RGName string `json:"rgName"`
|
||||
Status string `json:"status"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
UpdatedTime int `json:"updatedTime"`
|
||||
VXLanID int `json:"vxlanId"`
|
||||
}
|
||||
|
||||
type VinsList []Vins
|
||||
|
||||
type VinsSearchResp []VinsSearchRecord
|
||||
|
||||
type VnfRecord struct {
|
||||
ID int `json:"id"`
|
||||
AccountID int `json:"accountId"`
|
||||
Type string `json:"type"` // "DHCP", "NAT", "GW" etc
|
||||
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
|
||||
ExtNetID int `json:"ext_net_id"`
|
||||
ExtNetIP string `json:"ext_net_ip"`
|
||||
ExtNetMask int `json:"ext_net_mask"`
|
||||
DefaultGW string `json:"default_gw"`
|
||||
}
|
||||
type VinsRecord struct { // represents part of the response from API vins/get
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IPCidr string `json:"network"`
|
||||
VxLanID int `json:"vxlanId"`
|
||||
ExternalIP string `json:"externalIP"`
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
RgID int `json:"rgid"`
|
||||
RgName string `json:"rgName"`
|
||||
VNFs map[string]VnfRecord `json:"vnfs"`
|
||||
Desc string `json:"desc"`
|
||||
}
|
||||
|
||||
type VinsSearchRecord struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IPCidr string `json:"network"`
|
||||
VxLanID int `json:"vxlanId"`
|
||||
ExternalIP string `json:"externalIP"`
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
RgID int `json:"rgId"`
|
||||
RgName string `json:"rgName"`
|
||||
}
|
||||
@@ -33,13 +33,12 @@ package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -62,82 +61,78 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d",
|
||||
d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
||||
|
||||
apiToCall := VinsCreateInAccountAPI
|
||||
createInAcc := true
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
inAccReq := vins.CreateInAccountRequest{
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
inRGReq := vins.CreateInRGRequest{
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
argVal, argSet := d.GetOk("rg_id")
|
||||
if argSet && argVal.(int) > 0 {
|
||||
apiToCall = VinsCreateInRgAPI
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int)))
|
||||
createInAcc = false
|
||||
inRGReq.RGID = uint64(argVal.(int))
|
||||
} else {
|
||||
// RG ID either not set at all or set to 0 - user may want ViNS at account level
|
||||
argVal, argSet = d.GetOk("account_id")
|
||||
if !argSet || argVal.(int) <= 0 {
|
||||
// No valid Account ID (and no RG ID either) - cannot create ViNS
|
||||
return diag.Errorf("resourceVinsCreate: ViNS name %s - no valid account and/or resource group ID specified", d.Id())
|
||||
}
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", argVal.(int)))
|
||||
inAccReq.AccountID = uint64(argVal.(int))
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("ext_net_id") // NB: even if ext_net_id value is explicitly set to 0, argSet = false anyway
|
||||
if argSet {
|
||||
if argVal.(int) > 0 {
|
||||
// connect to specific external network
|
||||
urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int)))
|
||||
/*
|
||||
Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform!
|
||||
|
||||
// in case of specific ext net connection user may also want a particular IP address
|
||||
argVal, argSet = d.GetOk("ext_net_ip")
|
||||
if argSet && argVal.(string) != "" {
|
||||
urlValues.Add("extIp", argVal.(string))
|
||||
}
|
||||
*/
|
||||
inRGReq.ExtNetID = uint64(argVal.(int))
|
||||
} else {
|
||||
// ext_net_id is set to a negative value - connect to default external network
|
||||
// no particular IP address selection in this case
|
||||
urlValues.Add("extNetId", "0")
|
||||
inRGReq.ExtNetID = 0
|
||||
}
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("ipcidr")
|
||||
if argSet && argVal.(string) != "" {
|
||||
log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string))
|
||||
urlValues.Add("ipcidr", argVal.(string))
|
||||
inAccReq.IPCIDR = argVal.(string)
|
||||
inRGReq.IPCIDR = argVal.(string)
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("description")
|
||||
if argSet {
|
||||
urlValues.Add("desc", argVal.(string))
|
||||
inAccReq.Description = argVal.(string)
|
||||
inRGReq.Description = argVal.(string)
|
||||
}
|
||||
|
||||
apiResp, err := c.DecortAPICall(ctx, "POST", apiToCall, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
var vinsID uint64
|
||||
if createInAcc {
|
||||
apiResp, err := c.CloudBroker().VINS().CreateInAccount(ctx, inAccReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
vinsID = apiResp
|
||||
} else {
|
||||
apiResp, err := c.CloudBroker().VINS().CreateInRG(ctx, inRGReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
vinsID = apiResp
|
||||
}
|
||||
|
||||
d.SetId(apiResp) // update ID of the resource to tell Terraform that the ViNS resource exists
|
||||
vinsId, _ := strconv.Atoi(apiResp)
|
||||
d.SetId(strconv.FormatUint(vinsID, 10))
|
||||
|
||||
log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsId, d.Get("name").(string))
|
||||
log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsID, d.Get("name").(string))
|
||||
|
||||
// We may reuse dataSourceVinsRead here as we maintain similarity
|
||||
// between ViNS resource and ViNS data source schemas
|
||||
// ViNS resource read function will also update resource ID on success, so that Terraform
|
||||
// will know the resource exists (however, we already did it a few lines before)
|
||||
return dataSourceVinsRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if vinsFacts == "" {
|
||||
// if empty string is returned from utilityVinsCheckPresence then there is no
|
||||
// such ViNS and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty
|
||||
if vinsFacts == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
@@ -145,40 +140,39 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}
|
||||
}
|
||||
|
||||
func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
|
||||
log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d",
|
||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
vinsID, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
|
||||
// 1. Handle external network connection change
|
||||
oldExtNetId, newExtNedId := d.GetChange("ext_net_id")
|
||||
if oldExtNetId.(int) != newExtNedId.(int) {
|
||||
log.Debugf("resourceVinsUpdate: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int))
|
||||
|
||||
extnetParams := &url.Values{}
|
||||
extnetParams.Add("vinsId", d.Id())
|
||||
|
||||
if oldExtNetId.(int) > 0 {
|
||||
// there was preexisting external net connection - disconnect ViNS
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsExtNetDisconnectAPI, extnetParams)
|
||||
req := vins.ExtNetDisconnectRequest{VINSID: vinsID}
|
||||
|
||||
_, err := c.CloudBroker().VINS().ExtNetDisconnect(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if newExtNedId.(int) > 0 {
|
||||
// new external network connection requested - connect ViNS
|
||||
extnetParams.Add("netId", fmt.Sprintf("%d", newExtNedId.(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsExtNetConnectAPI, extnetParams)
|
||||
req := vins.ExtNetConnectRequest{
|
||||
VINSID: vinsID,
|
||||
NetID: uint64(newExtNedId.(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudBroker().VINS().ExtNetConnect(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we may reuse dataSourceVinsRead here as we maintain similarity
|
||||
// between Compute resource and Compute data source schemas
|
||||
return dataSourceVinsRead(ctx, d, m)
|
||||
}
|
||||
|
||||
@@ -187,7 +181,7 @@ func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface
|
||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
||||
|
||||
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if vinsFacts == "" {
|
||||
if vinsFacts == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -196,13 +190,14 @@ func resourceVinsDelete(ctx context.Context, d *schema.ResourceData, m interface
|
||||
return nil
|
||||
}
|
||||
|
||||
params := &url.Values{}
|
||||
params.Add("vinsId", d.Id())
|
||||
params.Add("force", "1") // disconnect all computes before deleting ViNS
|
||||
params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
_, err = c.DecortAPICall(ctx, "POST", VinsDeleteAPI, params)
|
||||
req := vins.DeleteRequest{
|
||||
VINSID: vinsFacts.ID,
|
||||
Force: true,
|
||||
Permanently: true,
|
||||
}
|
||||
|
||||
_, err = c.CloudBroker().VINS().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
@@ -33,44 +33,25 @@ package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
// On success this function returns a string, as returned by API vins/get, which could be unmarshalled
|
||||
// into VinsGetResp structure
|
||||
func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
|
||||
// This function tries to locate ViNS by one of the following algorithms depending
|
||||
// on the parameters passed:
|
||||
// - if resource group ID is specified -> it looks for a ViNS at the RG level
|
||||
// - if account ID is specifeid -> it looks for a ViNS at the account level
|
||||
//
|
||||
// If succeeded, it returns non empty string that contains JSON formatted facts about the
|
||||
// ViNS as returned by vins/get API call.
|
||||
// Otherwise it returns empty string and a meaningful error.
|
||||
//
|
||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||
// method for the Terraform resource Exists method.
|
||||
//
|
||||
|
||||
func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.RecordVINS, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
// make it possible to use "read" & "check presence" functions with ViNS ID set so
|
||||
// that Import of ViNS resource is possible
|
||||
idSet := false
|
||||
theId, err := strconv.Atoi(d.Id())
|
||||
if err != nil || theId <= 0 {
|
||||
vinsID, err := strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil || vinsID <= 0 {
|
||||
vinsId, argSet := d.GetOk("vins_id") // NB: vins_id is NOT present in vinsResource schema!
|
||||
if argSet {
|
||||
theId = vinsId.(int)
|
||||
vinsID = uint64(vinsId.(int))
|
||||
idSet = true
|
||||
}
|
||||
} else {
|
||||
@@ -78,76 +59,65 @@ func utilityVinsCheckPresence(ctx context.Context, d *schema.ResourceData, m int
|
||||
}
|
||||
|
||||
if idSet {
|
||||
// ViNS ID is specified, try to get compute instance straight by this ID
|
||||
log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", theId)
|
||||
urlValues.Add("vinsId", fmt.Sprintf("%d", theId))
|
||||
vinsFacts, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, urlValues)
|
||||
log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", vinsID)
|
||||
req := vins.GetRequest{VINSID: vinsID}
|
||||
|
||||
vinsFacts, err := c.CloudBroker().VINS().Get(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vinsFacts, nil
|
||||
}
|
||||
|
||||
// ID was not set in the schema upon entering this function - work through ViNS name
|
||||
// and Account / RG ID
|
||||
|
||||
vinsName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
// if ViNS name is not set. then we cannot locate ViNS
|
||||
return "", fmt.Errorf("Cannot check ViNS presence if ViNS name is empty")
|
||||
return nil, fmt.Errorf("Cannot check ViNS presence if ViNS name is empty")
|
||||
}
|
||||
req := vins.SearchRequest{
|
||||
Name: vinsName.(string),
|
||||
ShowAll: false,
|
||||
}
|
||||
urlValues.Add("name", vinsName.(string))
|
||||
urlValues.Add("show_all", "false")
|
||||
log.Debugf("utilityVinsCheckPresence: preparing to locate ViNS name %s", vinsName.(string))
|
||||
|
||||
rgId, rgSet := d.GetOk("rg_id")
|
||||
if rgSet {
|
||||
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to RG ID %d", rgId.(int))
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgId.(int)))
|
||||
req.RGID = uint64(rgId.(int))
|
||||
}
|
||||
|
||||
accountId, accountSet := d.GetOk("account_id")
|
||||
if accountSet {
|
||||
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to Account ID %d", accountId.(int))
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", accountId.(int)))
|
||||
req.AccountID = uint64(accountId.(int))
|
||||
}
|
||||
|
||||
apiResp, err := c.DecortAPICall(ctx, "POST", VinsSearchAPI, urlValues)
|
||||
vinsList, err := c.CloudBroker().VINS().Search(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// log.Debugf("%s", apiResp)
|
||||
// log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI)
|
||||
model := VinsSearchResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &model)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(model))
|
||||
for index, item := range model {
|
||||
log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(vinsList))
|
||||
for index, item := range vinsList {
|
||||
if item.Name == vinsName.(string) {
|
||||
if (accountSet && item.AccountID != accountId.(int)) ||
|
||||
(rgSet && item.RgID != rgId.(int)) {
|
||||
// double check that account ID and Rg ID match, if set in the schema
|
||||
if (accountSet && item.AccountID != uint64(accountId.(int))) ||
|
||||
(rgSet && item.RGID != uint64(rgId.(int))) {
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsCheckPresence: match ViNS name %s / ID %d, account ID %d, RG ID %d at index %d",
|
||||
item.Name, item.ID, item.AccountID, item.RgID, index)
|
||||
item.Name, item.ID, item.AccountID, item.RGID, index)
|
||||
|
||||
// element returned by API vins/search does not contain all information we may need to
|
||||
// manage ViNS, so we have to get detailed info by calling API vins/get
|
||||
rqValues := &url.Values{}
|
||||
rqValues.Add("vinsId", fmt.Sprintf("%d", item.ID))
|
||||
vinsGetResp, err := c.DecortAPICall(ctx, "POST", VinsGetAPI, rqValues)
|
||||
req := vins.GetRequest{VINSID: item.ID}
|
||||
|
||||
vinsGetResp, err := c.CloudBroker().VINS().Get(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vinsGetResp, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string))
|
||||
return nil, fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string))
|
||||
}
|
||||
|
||||
@@ -33,38 +33,27 @@ package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (VinsList, error) {
|
||||
vinsList := VinsList{}
|
||||
func utilityVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (vins.ListVINS, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
req := vins.ListRequest{}
|
||||
|
||||
if includeDeleted, ok := d.GetOk("include_deleted"); ok {
|
||||
urlValues.Add("includeDeleted", strconv.FormatBool(includeDeleted.(bool)))
|
||||
}
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsListCheckPresence")
|
||||
vinsListRaw, err := c.DecortAPICall(ctx, "POST", VinsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(vinsListRaw), &vinsList)
|
||||
vinsList, err := c.CloudBroker().VINS().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user