3.6.0
This commit is contained in:
@@ -34,12 +34,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 {
|
||||
@@ -48,128 +47,213 @@ 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.Set("vinses", acc.Vinses)
|
||||
d.Set("computes", flattenAccComputes(acc.Computes))
|
||||
d.Set("machines", flattenAccMachines(acc.Machines))
|
||||
flattenAccount(d, *acc)
|
||||
d.SetId(strconv.Itoa(acc.ID))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func flattenAccComputes(acs Computes) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"started": acs.Started,
|
||||
"stopped": acs.Stopped,
|
||||
func aclSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"can_be_deleted": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"explicit": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"right": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"user_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
res = append(res, temp)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccMachines(ams Machines) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"running": ams.Running,
|
||||
"halted": ams.Halted,
|
||||
func resourceLimitsSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"cu_c": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"cu_d": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"cu_i": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"cu_m": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"cu_np": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"gpu_units": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
res = append(res, temp)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, acls := range acls {
|
||||
temp := map[string]interface{}{
|
||||
"can_be_deleted": acls.CanBeDeleted,
|
||||
"explicit": acls.IsExplicit,
|
||||
"guid": acls.Guid,
|
||||
"right": acls.Rights,
|
||||
"status": acls.Status,
|
||||
"type": acls.Type,
|
||||
"user_group_id": acls.UgroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
func sepsSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"sep_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"data_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size_max": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
|
||||
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,
|
||||
func resourcesSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"current": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"disksize": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"extips": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"exttraffic": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"gpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"seps": {
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: sepsSchemaMake(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"reserved": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"disksize": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"extips": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"exttraffic": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"gpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"seps": {
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: sepsSchemaMake(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
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 flattenAccountSeps(seps map[string]map[string]ResourceSep) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for sepKey, sepVal := range seps {
|
||||
for dataKey, dataVal := range sepVal {
|
||||
temp := map[string]interface{}{
|
||||
"sep_id": sepKey,
|
||||
"data_name": dataKey,
|
||||
"disk_size": dataVal.DiskSize,
|
||||
"disk_size_max": dataVal.DiskSizeMax,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
func computesSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"started": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"stopped": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
|
||||
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,
|
||||
"seps": flattenAccountSeps(r.SEPs),
|
||||
func machinesSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"halted": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"running": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
res = append(res, temp)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -188,120 +272,7 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"current": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"disksize": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"extips": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"exttraffic": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"gpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"seps": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"sep_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"data_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size_max": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"reserved": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"disksize": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"extips": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"exttraffic": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"gpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"seps": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"sep_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"data_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size_max": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Schema: resourcesSchemaMake(),
|
||||
},
|
||||
},
|
||||
"ckey": {
|
||||
@@ -319,36 +290,7 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"can_be_deleted": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"explicit": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"right": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"user_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Schema: aclSchemaMake(),
|
||||
},
|
||||
},
|
||||
"company": {
|
||||
@@ -395,32 +337,7 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cu_c": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"cu_d": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"cu_i": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"cu_m": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"cu_np": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"gpu_units": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Schema: resourceLimitsSchemaMake(),
|
||||
},
|
||||
},
|
||||
"send_access_emails": {
|
||||
@@ -454,32 +371,14 @@ func dataSourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"started": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"stopped": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Schema: computesSchemaMake(),
|
||||
},
|
||||
},
|
||||
"machines": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"halted": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"running": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Schema: machinesSchemaMake(),
|
||||
},
|
||||
},
|
||||
"vinses": {
|
||||
|
||||
137
internal/service/cloudapi/account/flattens.go
Normal file
137
internal/service/cloudapi/account/flattens.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
|
||||
)
|
||||
|
||||
func flattenAccount(d *schema.ResourceData, acc AccountWithResources) error {
|
||||
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.Set("vinses", acc.Vinses)
|
||||
d.Set("computes", flattenAccComputes(acc.Computes))
|
||||
d.Set("machines", flattenAccMachines(acc.Machines))
|
||||
|
||||
if username, ok := d.GetOk("username"); ok {
|
||||
d.Set("username", username)
|
||||
} else {
|
||||
d.Set("username", acc.Acl[0].UgroupID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func flattenAccComputes(acs Computes) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"started": acs.Started,
|
||||
"stopped": acs.Stopped,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccMachines(ams Machines) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"running": ams.Running,
|
||||
"halted": ams.Halted,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, acls := range acls {
|
||||
temp := map[string]interface{}{
|
||||
"can_be_deleted": acls.CanBeDeleted,
|
||||
"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 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 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 flattenAccountSeps(seps map[string]map[string]ResourceSep) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for sepKey, sepVal := range seps {
|
||||
for dataKey, dataVal := range sepVal {
|
||||
temp := map[string]interface{}{
|
||||
"sep_id": sepKey,
|
||||
"data_name": dataKey,
|
||||
"disk_size": dataVal.DiskSize,
|
||||
"disk_size_max": dataVal.DiskSizeMax,
|
||||
}
|
||||
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,
|
||||
"seps": flattenAccountSeps(r.SEPs),
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
@@ -43,7 +43,7 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"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"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
)
|
||||
|
||||
func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -122,13 +122,10 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(accountId)
|
||||
d.Set("account_id", accountId)
|
||||
accIdParsed, _ := strconv.Atoi(accountId)
|
||||
|
||||
diagnostics := resourceAccountRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
return diagnostics
|
||||
}
|
||||
d.SetId(accountId)
|
||||
d.Set("account_id", accIdParsed)
|
||||
|
||||
urlValues = &url.Values{}
|
||||
|
||||
@@ -167,44 +164,52 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourceAccountRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceAccountRead")
|
||||
log.Debugf("resourceAccountRead: called for account with ID: %v", d.Id())
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
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)
|
||||
d.Set("vinses", acc.Vinses)
|
||||
d.Set("computes", flattenAccComputes(acc.Computes))
|
||||
d.Set("machines", flattenAccMachines(acc.Machines))
|
||||
hasChanged := false
|
||||
|
||||
switch acc.Status {
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceAccountCreate(ctx, d, m)
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The account is in progress with status: %s", acc.Status)
|
||||
case status.Deleted:
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("accountId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountRestoreAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Disabled:
|
||||
log.Debugf("The account is in status: %s, troubles may occur with update. Please, enable account first.", acc.Status)
|
||||
case status.Confirmed:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
acc, err = utilityAccountCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
flattenAccount(d, *acc)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -234,11 +239,49 @@ func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, m interf
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceAccountEdit")
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
|
||||
acc, err := utilityAccountCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged := false
|
||||
|
||||
switch acc.Status {
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceAccountCreate(ctx, d, m)
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The account is in progress with status: %s", acc.Status)
|
||||
case status.Deleted:
|
||||
urlVal := &url.Values{}
|
||||
urlVal.Add("accountId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", accountRestoreAPI, urlVal)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Disabled:
|
||||
log.Debugf("The account is in status: %s, troubles may occur with update. Please, enable account first.", acc.Status)
|
||||
case status.Confirmed:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
acc, err = utilityAccountCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("enable") {
|
||||
api := accountDisableAPI
|
||||
enable := d.Get("enable").(bool)
|
||||
@@ -424,7 +467,7 @@ func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
return resourceAccountRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func isContainsUser(els []interface{}, el interface{}) bool {
|
||||
@@ -553,7 +596,6 @@ func resourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"dc_location": {
|
||||
@@ -564,120 +606,7 @@ func resourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"current": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"disksize": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"extips": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"exttraffic": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"gpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"seps": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"sep_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"data_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size_max": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"reserved": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"disksize": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"extips": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"exttraffic": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"gpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"seps": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"sep_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"data_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size": {
|
||||
Type: schema.TypeFloat,
|
||||
Computed: true,
|
||||
},
|
||||
"disk_size_max": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Schema: resourcesSchemaMake(),
|
||||
},
|
||||
},
|
||||
"ckey": {
|
||||
@@ -695,36 +624,7 @@ func resourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"can_be_deleted": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"explicit": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"right": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"user_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Schema: aclSchemaMake(),
|
||||
},
|
||||
},
|
||||
"company": {
|
||||
@@ -790,32 +690,14 @@ func resourceAccountSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"started": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"stopped": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Schema: computesSchemaMake(),
|
||||
},
|
||||
},
|
||||
"machines": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"halted": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"running": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Schema: machinesSchemaMake(),
|
||||
},
|
||||
},
|
||||
"vinses": {
|
||||
@@ -831,7 +713,7 @@ func ResourceAccount() *schema.Resource {
|
||||
|
||||
CreateContext: resourceAccountCreate,
|
||||
ReadContext: resourceAccountRead,
|
||||
UpdateContext: resourceAccountEdit,
|
||||
UpdateContext: resourceAccountUpdate,
|
||||
DeleteContext: resourceAccountDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -34,8 +34,8 @@ package bservice
|
||||
|
||||
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"
|
||||
@@ -47,70 +47,13 @@ func dataSourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m i
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("account_id", bs.AccountId)
|
||||
d.Set("account_name", bs.AccountName)
|
||||
d.Set("base_domain", bs.BaseDomain)
|
||||
d.Set("computes", flattenBasicServiceComputes(bs.Computes))
|
||||
d.Set("cpu_total", bs.CPUTotal)
|
||||
d.Set("created_by", bs.CreatedBy)
|
||||
d.Set("created_time", bs.CreatedTime)
|
||||
d.Set("deleted_by", bs.DeletedBy)
|
||||
d.Set("deleted_time", bs.DeletedTime)
|
||||
d.Set("disk_total", bs.DiskTotal)
|
||||
d.Set("gid", bs.GID)
|
||||
d.Set("groups", bs.Groups)
|
||||
d.Set("groups_name", bs.GroupsName)
|
||||
d.Set("guid", bs.GUID)
|
||||
d.Set("milestones", bs.Milestones)
|
||||
d.Set("service_name", bs.Name)
|
||||
d.Set("parent_srv_id", bs.ParentSrvId)
|
||||
d.Set("parent_srv_type", bs.ParentSrvType)
|
||||
d.Set("ram_total", bs.RamTotal)
|
||||
d.Set("rg_id", bs.RGID)
|
||||
d.Set("rg_name", bs.RGName)
|
||||
d.Set("snapshots", flattenBasicServiceSnapshots(bs.Snapshots))
|
||||
d.Set("ssh_key", bs.SSHKey)
|
||||
d.Set("ssh_user", bs.SSHUser)
|
||||
d.Set("status", bs.Status)
|
||||
d.Set("tech_status", bs.TechStatus)
|
||||
d.Set("updated_by", bs.UpdatedBy)
|
||||
d.Set("updated_time", bs.UpdatedTime)
|
||||
d.Set("user_managed", bs.UserManaged)
|
||||
d.SetId(strconv.Itoa(bs.ID))
|
||||
|
||||
flattenService(d, bs)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func flattenBasicServiceComputes(bscs BasicServiceComputes) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, bsc := range bscs {
|
||||
temp := map[string]interface{}{
|
||||
"compgroup_id": bsc.CompGroupId,
|
||||
"compgroup_name": bsc.CompGroupName,
|
||||
"compgroup_role": bsc.CompGroupRole,
|
||||
"id": bsc.ID,
|
||||
"name": bsc.Name,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenBasicServiceSnapshots(bsrvss BasicServiceSnapshots) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, bsrvs := range bsrvss {
|
||||
temp := map[string]interface{}{
|
||||
"guid": bsrvs.GUID,
|
||||
"label": bsrvs.Label,
|
||||
"timestamp": bsrvs.Timestamp,
|
||||
"valid": bsrvs.Valid,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func dataSourceBasicServiceSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"service_id": {
|
||||
|
||||
66
internal/service/cloudapi/bservice/flattens.go
Normal file
66
internal/service/cloudapi/bservice/flattens.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package bservice
|
||||
|
||||
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
|
||||
func flattenService(d *schema.ResourceData, bs *BasicServiceExtend) {
|
||||
d.Set("account_id", bs.AccountId)
|
||||
d.Set("account_name", bs.AccountName)
|
||||
d.Set("base_domain", bs.BaseDomain)
|
||||
d.Set("computes", flattenBasicServiceComputes(bs.Computes))
|
||||
d.Set("cpu_total", bs.CPUTotal)
|
||||
d.Set("created_by", bs.CreatedBy)
|
||||
d.Set("created_time", bs.CreatedTime)
|
||||
d.Set("deleted_by", bs.DeletedBy)
|
||||
d.Set("deleted_time", bs.DeletedTime)
|
||||
d.Set("disk_total", bs.DiskTotal)
|
||||
d.Set("gid", bs.GID)
|
||||
d.Set("groups", bs.Groups)
|
||||
d.Set("groups_name", bs.GroupsName)
|
||||
d.Set("guid", bs.GUID)
|
||||
d.Set("milestones", bs.Milestones)
|
||||
d.Set("service_name", bs.Name)
|
||||
d.Set("service_id", bs.ID)
|
||||
d.Set("parent_srv_id", bs.ParentSrvId)
|
||||
d.Set("parent_srv_type", bs.ParentSrvType)
|
||||
d.Set("ram_total", bs.RamTotal)
|
||||
d.Set("rg_id", bs.RGID)
|
||||
d.Set("rg_name", bs.RGName)
|
||||
d.Set("snapshots", flattenBasicServiceSnapshots(bs.Snapshots))
|
||||
d.Set("ssh_key", bs.SSHKey)
|
||||
d.Set("ssh_user", bs.SSHUser)
|
||||
d.Set("status", bs.Status)
|
||||
d.Set("tech_status", bs.TechStatus)
|
||||
d.Set("updated_by", bs.UpdatedBy)
|
||||
d.Set("updated_time", bs.UpdatedTime)
|
||||
d.Set("user_managed", bs.UserManaged)
|
||||
}
|
||||
|
||||
func flattenBasicServiceComputes(bscs BasicServiceComputes) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, bsc := range bscs {
|
||||
temp := map[string]interface{}{
|
||||
"compgroup_id": bsc.CompGroupId,
|
||||
"compgroup_name": bsc.CompGroupName,
|
||||
"compgroup_role": bsc.CompGroupRole,
|
||||
"id": bsc.ID,
|
||||
"name": bsc.Name,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenBasicServiceSnapshots(bsrvss BasicServiceSnapshots) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, bsrvs := range bsrvss {
|
||||
temp := map[string]interface{}{
|
||||
"guid": bsrvs.GUID,
|
||||
"label": bsrvs.Label,
|
||||
"timestamp": bsrvs.Timestamp,
|
||||
"valid": bsrvs.Valid,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -42,6 +42,7 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"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/status"
|
||||
)
|
||||
|
||||
func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -50,6 +51,15 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
haveRGID, err := existRGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveRGID {
|
||||
return diag.Errorf("resourceBasicServiceCreate: can't create basic service because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
|
||||
urlValues.Add("name", d.Get("service_name").(string))
|
||||
urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int)))
|
||||
|
||||
@@ -65,8 +75,10 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
serviceIdParsed, _ := strconv.Atoi(serviceId)
|
||||
|
||||
d.SetId(serviceId)
|
||||
d.Set("service_id", serviceId)
|
||||
d.Set("service_id", serviceIdParsed)
|
||||
|
||||
diagnostics := resourceBasicServiceRead(ctx, d, m)
|
||||
if diagnostics != nil {
|
||||
@@ -79,42 +91,55 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
|
||||
func resourceBasicServiceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceBasicServiceRead")
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
bs, err := utilityBasicServiceCheckPresence(ctx, d, m)
|
||||
if bs == nil {
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("account_id", bs.AccountId)
|
||||
d.Set("account_name", bs.AccountName)
|
||||
d.Set("base_domain", bs.BaseDomain)
|
||||
d.Set("computes", flattenBasicServiceComputes(bs.Computes))
|
||||
d.Set("cpu_total", bs.CPUTotal)
|
||||
d.Set("created_by", bs.CreatedBy)
|
||||
d.Set("created_time", bs.CreatedTime)
|
||||
d.Set("deleted_by", bs.DeletedBy)
|
||||
d.Set("deleted_time", bs.DeletedTime)
|
||||
d.Set("disk_total", bs.DiskTotal)
|
||||
d.Set("gid", bs.GID)
|
||||
d.Set("groups", bs.Groups)
|
||||
d.Set("groups_name", bs.GroupsName)
|
||||
d.Set("guid", bs.GUID)
|
||||
d.Set("milestones", bs.Milestones)
|
||||
d.Set("service_name", bs.Name)
|
||||
d.Set("service_id", bs.ID)
|
||||
d.Set("parent_srv_id", bs.ParentSrvId)
|
||||
d.Set("parent_srv_type", bs.ParentSrvType)
|
||||
d.Set("ram_total", bs.RamTotal)
|
||||
d.Set("rg_id", bs.RGID)
|
||||
d.Set("rg_name", bs.RGName)
|
||||
d.Set("snapshots", flattenBasicServiceSnapshots(bs.Snapshots))
|
||||
d.Set("ssh_key", bs.SSHKey)
|
||||
d.Set("ssh_user", bs.SSHUser)
|
||||
d.Set("status", bs.Status)
|
||||
d.Set("tech_status", bs.TechStatus)
|
||||
d.Set("updated_by", bs.UpdatedBy)
|
||||
d.Set("updated_time", bs.UpdatedTime)
|
||||
d.Set("user_managed", bs.UserManaged)
|
||||
hasChanged := false
|
||||
|
||||
switch bs.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The basic service is in status: %s, please, contact support for more information", bs.Status)
|
||||
case status.Created:
|
||||
case status.Enabled:
|
||||
case status.Enabling:
|
||||
case status.Disabled:
|
||||
log.Debugf("The basic service is in status: %s, troubles can occur with the update. Please, enable bservice first.", bs.Status)
|
||||
case status.Disabling:
|
||||
log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status)
|
||||
case status.Deleted:
|
||||
urlVal := &url.Values{}
|
||||
urlVal.Add("serviceId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", bserviceRestoreAPI, urlVal)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Deleting:
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceBasicServiceCreate(ctx, d, m)
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The basic service is in progress with status: %s", bs.Status)
|
||||
case status.Restoring:
|
||||
case status.Reconfiguring:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
bs, err = utilityBasicServiceCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
flattenService(d, bs)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -144,10 +169,65 @@ func resourceBasicServiceDelete(ctx context.Context, d *schema.ResourceData, m i
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceBasicServiceEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceBasicServiceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceBasicServiceEdit")
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
haveRGID, err := existRGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveRGID {
|
||||
return diag.Errorf("resourceBasicServiceUpdate: can't create basic service because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
|
||||
bs, err := utilityBasicServiceCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged := false
|
||||
|
||||
switch bs.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The basic service is in status: %s, please, contact support for more information", bs.Status)
|
||||
case status.Created:
|
||||
case status.Enabled:
|
||||
case status.Enabling:
|
||||
case status.Disabled:
|
||||
log.Debugf("The basic service is in status: %s, troubles can occur with the update. Please, enable bservice first.", bs.Status)
|
||||
case status.Disabling:
|
||||
log.Debugf("The basic service is in status: %s, troubles can occur with the update.", bs.Status)
|
||||
case status.Deleted:
|
||||
urlVal := &url.Values{}
|
||||
urlVal.Add("serviceId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", bserviceRestoreAPI, urlVal)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Deleting:
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceBasicServiceCreate(ctx, d, m)
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The basic service is in progress with status: %s", bs.Status)
|
||||
case status.Restoring:
|
||||
case status.Reconfiguring:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
bs, err = utilityBasicServiceCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
urlValues := &url.Values{}
|
||||
if d.HasChange("enable") {
|
||||
api := bserviceDisableAPI
|
||||
@@ -508,7 +588,7 @@ func ResourceBasicService() *schema.Resource {
|
||||
|
||||
CreateContext: resourceBasicServiceCreate,
|
||||
ReadContext: resourceBasicServiceRead,
|
||||
UpdateContext: resourceBasicServiceEdit,
|
||||
UpdateContext: resourceBasicServiceUpdate,
|
||||
DeleteContext: resourceBasicServiceDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package bservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
rgList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
rgListAPI := "/restmachine/cloudapi/rg/list"
|
||||
|
||||
rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(rgListRaw), &rgList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveRG := false
|
||||
rgId := d.Get("rg_id").(int)
|
||||
for _, rg := range rgList {
|
||||
if rg.ID == rgId {
|
||||
haveRG = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveRG, nil
|
||||
}
|
||||
@@ -34,7 +34,6 @@ package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -42,117 +41,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func flattenDiskComputes(computes map[string]string) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for computeKey, computeVal := range computes {
|
||||
temp := map[string]interface{}{
|
||||
"compute_id": computeKey,
|
||||
"compute_name": computeVal,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
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),
|
||||
"computes": flattenDiskComputes(disk.Computes),
|
||||
"boot_partition": disk.BootPartition,
|
||||
"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,
|
||||
"present_to": disk.PresentTo,
|
||||
"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,
|
||||
"shareable": disk.Shareable,
|
||||
"size_max": disk.SizeMax,
|
||||
"size_used": disk.SizeUsed,
|
||||
"snapshots": flattenDiskSnapshotList(disk.Snapshots),
|
||||
"status": disk.Status,
|
||||
"tech_status": disk.TechStatus,
|
||||
"type": disk.Type,
|
||||
"vmid": disk.VMID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
|
||||
}
|
||||
|
||||
func flattenDiskSnapshotList(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, disksListAPI)
|
||||
if err != nil {
|
||||
|
||||
166
internal/service/cloudapi/disks/flattens.go
Normal file
166
internal/service/cloudapi/disks/flattens.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package disks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func flattenDisk(d *schema.ResourceData, disk Disk) {
|
||||
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("computes", flattenDiskComputes(disk.Computes))
|
||||
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("present_to", disk.PresentTo)
|
||||
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("shareable", disk.Shareable)
|
||||
d.Set("snapshots", flattenDiskSnapshotList(disk.Snapshots))
|
||||
d.Set("status", disk.Status)
|
||||
d.Set("tech_status", disk.TechStatus)
|
||||
d.Set("type", disk.Type)
|
||||
d.Set("vmid", disk.VMID)
|
||||
}
|
||||
|
||||
func flattenDiskSnapshotList(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 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),
|
||||
"computes": flattenDiskComputes(disk.Computes),
|
||||
"boot_partition": disk.BootPartition,
|
||||
"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,
|
||||
"present_to": disk.PresentTo,
|
||||
"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,
|
||||
"shareable": disk.Shareable,
|
||||
"size_max": disk.SizeMax,
|
||||
"size_used": disk.SizeUsed,
|
||||
"snapshots": flattenDiskSnapshotList(disk.Snapshots),
|
||||
"status": disk.Status,
|
||||
"tech_status": disk.TechStatus,
|
||||
"type": disk.Type,
|
||||
"vmid": disk.VMID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
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 flattenDiskComputes(computes map[string]string) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for computeKey, computeVal := range computes {
|
||||
temp := map[string]interface{}{
|
||||
"compute_id": computeKey,
|
||||
"compute_name": computeVal,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
|
||||
accountList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
accountListAPI := "/restmachine/cloudapi/account/list"
|
||||
|
||||
accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountListRaw), &accountList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveAccount := false
|
||||
|
||||
myAccount := d.Get("account_id").(int)
|
||||
for _, account := range accountList {
|
||||
if account.ID == myAccount {
|
||||
haveAccount = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return haveAccount, nil
|
||||
}
|
||||
|
||||
func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
|
||||
locationList := []struct {
|
||||
GID int `json:"gid"`
|
||||
}{}
|
||||
|
||||
locationsListAPI := "/restmachine/cloudapi/locations/list"
|
||||
|
||||
locationListRaw, err := c.DecortAPICall(ctx, "POST", locationsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(locationListRaw), &locationList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveGID := false
|
||||
|
||||
gid := d.Get("gid").(int)
|
||||
for _, location := range locationList {
|
||||
if location.GID == gid {
|
||||
haveGID = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveGID, nil
|
||||
}
|
||||
@@ -34,17 +34,16 @@ package disks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"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/dc"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -55,10 +54,26 @@ func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
||||
urlValues.Add("gid", fmt.Sprintf("%d", d.Get("gid").(int)))
|
||||
haveAccount, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if !haveAccount {
|
||||
return diag.Errorf("resourceDiskCreate: can't create Disk because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceDiskCreate: can't create Disk because GID %d is not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
|
||||
urlValues.Add("name", d.Get("disk_name").(string))
|
||||
urlValues.Add("size", fmt.Sprintf("%d", d.Get("size_max").(int)))
|
||||
urlValues.Add("size", strconv.Itoa(d.Get("size_max").(int)))
|
||||
if typeRaw, ok := d.GetOk("type"); ok {
|
||||
urlValues.Add("type", strings.ToUpper(typeRaw.(string)))
|
||||
} else {
|
||||
@@ -85,7 +100,7 @@ func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
|
||||
urlValues = &url.Values{}
|
||||
|
||||
d.SetId(diskId) // update ID of the resource to tell Terraform that the disk resource exists
|
||||
d.SetId(diskId)
|
||||
|
||||
if iotuneRaw, ok := d.GetOk("iotune"); ok {
|
||||
iot := iotuneRaw.([]interface{})[0]
|
||||
@@ -136,19 +151,18 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
hasChangeState := false
|
||||
if disk.Status == status.Destroyed || disk.Status == status.Purged {
|
||||
|
||||
switch disk.Status {
|
||||
case status.Destroyed, status.Purged:
|
||||
d.Set("disk_id", 0)
|
||||
return resourceDiskCreate(ctx, d, m)
|
||||
} else if disk.Status == status.Deleted {
|
||||
case status.Deleted:
|
||||
hasChangeState = true
|
||||
urlValues.Add("diskId", d.Id())
|
||||
urlValues.Add("reason", d.Get("reason").(string))
|
||||
@@ -157,79 +171,84 @@ func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
case status.Assigned:
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The disk is in status: %s, please, contact support for more information", disk.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Allocated:
|
||||
case status.Unallocated:
|
||||
}
|
||||
|
||||
if hasChangeState {
|
||||
urlValues = &url.Values{}
|
||||
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("computes", flattenDiskComputes(disk.Computes))
|
||||
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("present_to", disk.PresentTo)
|
||||
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("shareable", disk.Shareable)
|
||||
d.Set("snapshots", flattenDiskSnapshotList(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 warnings.Get()
|
||||
}
|
||||
|
||||
func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
warnings := dc.Warnings{}
|
||||
urlValues := &url.Values{}
|
||||
|
||||
haveAccount, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if !haveAccount {
|
||||
return diag.Errorf("resourceDiskUpdate: can't update Disk because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceDiskUpdate: can't update Disk because GID %d is not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
|
||||
disk, err := utilityDiskCheckPresence(ctx, d, m)
|
||||
if disk == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChangeState := false
|
||||
|
||||
switch disk.Status {
|
||||
case status.Destroyed, status.Purged:
|
||||
d.Set("disk_id", 0)
|
||||
return resourceDiskCreate(ctx, d, m)
|
||||
case status.Deleted:
|
||||
hasChangeState = true
|
||||
urlValues.Add("diskId", d.Id())
|
||||
urlValues.Add("reason", d.Get("reason").(string))
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
case status.Assigned:
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The disk is in status: %s, please, contact support for more information", disk.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Allocated:
|
||||
case status.Unallocated:
|
||||
}
|
||||
|
||||
if hasChangeState {
|
||||
disk, err = utilityDiskCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if d.HasChange("size_max") {
|
||||
@@ -238,7 +257,7 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
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)))
|
||||
urlValues.Add("size", strconv.Itoa(newSize.(int)))
|
||||
_, err := c.DecortAPICall(ctx, "POST", disksResizeAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -310,11 +329,9 @@ func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
|
||||
func resourceDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
disk, err := utilityDiskCheckPresence(ctx, d, m)
|
||||
if disk == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if disk.Status == status.Destroyed || disk.Status == status.Purged {
|
||||
return nil
|
||||
@@ -363,13 +380,6 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Description: "Pool for disk location",
|
||||
},
|
||||
"present_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
@@ -412,85 +422,6 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"disk_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Disk ID. Duplicates the value of the ID parameter",
|
||||
},
|
||||
"account_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "The name of the subscriber '(account') to whom this disk belongs",
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"boot_partition": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Number of disk partitions",
|
||||
},
|
||||
"computes": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Created time",
|
||||
},
|
||||
"deleted_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Deleted time",
|
||||
},
|
||||
"destruction_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Time of final deletion",
|
||||
},
|
||||
"devicename": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the device",
|
||||
},
|
||||
"disk_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Disk path",
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Disk ID on the storage side",
|
||||
},
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Image ID",
|
||||
},
|
||||
"images": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "IDs of images using the disk",
|
||||
},
|
||||
"iotune": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
@@ -579,6 +510,91 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
},
|
||||
},
|
||||
},
|
||||
"present_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"disk_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Disk ID. Duplicates the value of the ID parameter",
|
||||
},
|
||||
"account_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "The name of the subscriber '(account') to whom this disk belongs",
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"boot_partition": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Number of disk partitions",
|
||||
},
|
||||
"computes": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Created time",
|
||||
},
|
||||
"deleted_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Deleted time",
|
||||
},
|
||||
"destruction_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Time of final deletion",
|
||||
},
|
||||
"devicename": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the device",
|
||||
},
|
||||
"disk_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Disk path",
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Disk ID on the storage side",
|
||||
},
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Image ID",
|
||||
},
|
||||
"images": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "IDs of images using the disk",
|
||||
},
|
||||
"iqn": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
|
||||
@@ -39,21 +39,20 @@ import (
|
||||
|
||||
"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/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceDiskSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
urlValues := &url.Values{}
|
||||
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)
|
||||
}
|
||||
|
||||
snapshots := disk.Snapshots
|
||||
snapshot := Snapshot{}
|
||||
label := d.Get("label").(string)
|
||||
@@ -190,17 +189,17 @@ func resourceDiskSnapshotSchemaMake() map[string]*schema.Schema {
|
||||
Default: false,
|
||||
Description: "Needed in order to make a snapshot rollback",
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "ID of the snapshot",
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Snapshot time",
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "ID of the snapshot",
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
|
||||
@@ -38,8 +38,8 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
@@ -50,8 +50,12 @@ func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m int
|
||||
|
||||
disk := &Disk{}
|
||||
|
||||
if d.Get("disk_id").(int) == 0 {
|
||||
urlValues.Add("diskId", d.Id())
|
||||
if d.Get("disk_id") != nil {
|
||||
if d.Get("disk_id").(int) == 0 {
|
||||
urlValues.Add("diskId", d.Id())
|
||||
} else {
|
||||
urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int)))
|
||||
}
|
||||
} else {
|
||||
urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int)))
|
||||
}
|
||||
|
||||
@@ -41,59 +41,6 @@ import (
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func flattenImage(d *schema.ResourceData, img *ImageExtend) {
|
||||
d.Set("unc_path", img.UNCPath)
|
||||
d.Set("ckey", img.CKey)
|
||||
d.Set("account_id", img.AccountId)
|
||||
d.Set("acl", img.Acl)
|
||||
d.Set("architecture", img.Architecture)
|
||||
d.Set("boot_type", img.BootType)
|
||||
d.Set("bootable", img.Bootable)
|
||||
d.Set("compute_ci_id", img.ComputeCiId)
|
||||
d.Set("deleted_time", img.DeletedTime)
|
||||
d.Set("desc", img.Description)
|
||||
d.Set("drivers", img.Drivers)
|
||||
d.Set("enabled", img.Enabled)
|
||||
d.Set("gid", img.GridId)
|
||||
d.Set("guid", img.GUID)
|
||||
d.Set("history", flattenHistory(img.History))
|
||||
d.Set("hot_resize", img.HotResize)
|
||||
d.Set("image_id", img.Id)
|
||||
d.Set("last_modified", img.LastModified)
|
||||
d.Set("link_to", img.LinkTo)
|
||||
d.Set("milestones", img.Milestones)
|
||||
d.Set("image_name", img.Name)
|
||||
d.Set("password", img.Password)
|
||||
d.Set("pool_name", img.Pool)
|
||||
d.Set("provider_name", img.ProviderName)
|
||||
d.Set("purge_attempts", img.PurgeAttempts)
|
||||
d.Set("present_to", img.PresentTo)
|
||||
d.Set("res_id", img.ResId)
|
||||
d.Set("rescuecd", img.RescueCD)
|
||||
d.Set("sep_id", img.SepId)
|
||||
d.Set("shared_with", img.SharedWith)
|
||||
d.Set("size", img.Size)
|
||||
d.Set("status", img.Status)
|
||||
d.Set("tech_status", img.TechStatus)
|
||||
d.Set("type", img.Type)
|
||||
d.Set("username", img.Username)
|
||||
d.Set("version", img.Version)
|
||||
}
|
||||
|
||||
func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
|
||||
56
internal/service/cloudapi/image/flattens.go
Normal file
56
internal/service/cloudapi/image/flattens.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package image
|
||||
|
||||
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func flattenImage(d *schema.ResourceData, img *ImageExtend) {
|
||||
d.Set("unc_path", img.UNCPath)
|
||||
d.Set("ckey", img.CKey)
|
||||
d.Set("account_id", img.AccountId)
|
||||
d.Set("acl", img.Acl)
|
||||
d.Set("architecture", img.Architecture)
|
||||
d.Set("boot_type", img.BootType)
|
||||
d.Set("bootable", img.Bootable)
|
||||
d.Set("compute_ci_id", img.ComputeCiId)
|
||||
d.Set("deleted_time", img.DeletedTime)
|
||||
d.Set("desc", img.Description)
|
||||
d.Set("drivers", img.Drivers)
|
||||
d.Set("enabled", img.Enabled)
|
||||
d.Set("gid", img.GridId)
|
||||
d.Set("guid", img.GUID)
|
||||
d.Set("history", flattenHistory(img.History))
|
||||
d.Set("hot_resize", img.HotResize)
|
||||
d.Set("image_id", img.Id)
|
||||
d.Set("last_modified", img.LastModified)
|
||||
d.Set("link_to", img.LinkTo)
|
||||
d.Set("milestones", img.Milestones)
|
||||
d.Set("image_name", img.Name)
|
||||
d.Set("password", img.Password)
|
||||
d.Set("pool_name", img.Pool)
|
||||
d.Set("provider_name", img.ProviderName)
|
||||
d.Set("purge_attempts", img.PurgeAttempts)
|
||||
d.Set("present_to", img.PresentTo)
|
||||
d.Set("res_id", img.ResId)
|
||||
d.Set("rescuecd", img.RescueCD)
|
||||
d.Set("sep_id", img.SepId)
|
||||
d.Set("shared_with", img.SharedWith)
|
||||
d.Set("size", img.Size)
|
||||
d.Set("status", img.Status)
|
||||
d.Set("tech_status", img.TechStatus)
|
||||
d.Set("type", img.Type)
|
||||
d.Set("username", img.Username)
|
||||
d.Set("version", img.Version)
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
|
||||
accountList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
accountListAPI := "/restmachine/cloudapi/account/list"
|
||||
|
||||
accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountListRaw), &accountList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveAccount := false
|
||||
|
||||
myAccount := d.Get("account_id").(int)
|
||||
for _, account := range accountList {
|
||||
if account.ID == myAccount {
|
||||
haveAccount = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return haveAccount, nil
|
||||
}
|
||||
|
||||
func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
|
||||
locationList := []struct {
|
||||
GID int `json:"gid"`
|
||||
}{}
|
||||
|
||||
locationsListAPI := "/restmachine/cloudapi/locations/list"
|
||||
|
||||
locationListRaw, err := c.DecortAPICall(ctx, "POST", locationsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(locationListRaw), &locationList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveGID := false
|
||||
|
||||
gid := d.Get("gid").(int)
|
||||
for _, location := range locationList {
|
||||
if location.GID == gid {
|
||||
haveGID = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveGID, nil
|
||||
}
|
||||
@@ -40,14 +40,35 @@ import (
|
||||
|
||||
"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/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
)
|
||||
|
||||
func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceImageCreate: can't create Image because GID %d is not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("account_id"); ok {
|
||||
haveAccountID, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveAccountID {
|
||||
return diag.Errorf("resourceImageCreate: can't create Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
@@ -96,13 +117,7 @@ func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
if architecture, ok := d.GetOk("architecture"); ok {
|
||||
urlValues.Add("architecture", architecture.(string))
|
||||
}
|
||||
/* uncomment then OK
|
||||
imageId, err := c.DecortAPICall(ctx, "POST", imageCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
*/
|
||||
//innovation
|
||||
|
||||
res, err := c.DecortAPICall(ctx, "POST", imageCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -141,41 +156,17 @@ func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("unc_path", img.UNCPath)
|
||||
d.Set("ckey", img.CKey)
|
||||
d.Set("account_id", img.AccountId)
|
||||
d.Set("acl", img.Acl)
|
||||
d.Set("architecture", img.Architecture)
|
||||
d.Set("boot_type", img.BootType)
|
||||
d.Set("bootable", img.Bootable)
|
||||
d.Set("compute_ci_id", img.ComputeCiId)
|
||||
d.Set("deleted_time", img.DeletedTime)
|
||||
d.Set("desc", img.Description)
|
||||
d.Set("drivers", img.Drivers)
|
||||
d.Set("enabled", img.Enabled)
|
||||
d.Set("gid", img.GridId)
|
||||
d.Set("guid", img.GUID)
|
||||
d.Set("history", flattenHistory(img.History))
|
||||
d.Set("hot_resize", img.HotResize)
|
||||
d.Set("image_id", img.Id)
|
||||
d.Set("last_modified", img.LastModified)
|
||||
d.Set("link_to", img.LinkTo)
|
||||
d.Set("milestones", img.Milestones)
|
||||
d.Set("image_name", img.Name)
|
||||
d.Set("password", img.Password)
|
||||
d.Set("pool_name", img.Pool)
|
||||
d.Set("provider_name", img.ProviderName)
|
||||
d.Set("purge_attempts", img.PurgeAttempts)
|
||||
d.Set("res_id", img.ResId)
|
||||
d.Set("rescuecd", img.RescueCD)
|
||||
d.Set("sep_id", img.SepId)
|
||||
d.Set("shared_with", img.SharedWith)
|
||||
d.Set("size", img.Size)
|
||||
d.Set("status", img.Status)
|
||||
d.Set("tech_status", img.TechStatus)
|
||||
d.Set("type", img.Type)
|
||||
d.Set("username", img.Username)
|
||||
d.Set("version", img.Version)
|
||||
switch img.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Destroyed, status.Purged:
|
||||
d.SetId("")
|
||||
return resourceImageCreate(ctx, d, m)
|
||||
}
|
||||
|
||||
flattenImage(d, img)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -222,9 +213,47 @@ 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())
|
||||
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceImageUpdate: can't update Image because GID %d is not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("account_id"); ok {
|
||||
haveAccountID, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveAccountID {
|
||||
return diag.Errorf("resourceImageUpdate: can't update Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if image == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
switch image.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The image is in status: %s, please, contact support for more information", image.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Destroyed, status.Purged:
|
||||
d.SetId("")
|
||||
return resourceImageCreate(ctx, d, m)
|
||||
}
|
||||
|
||||
if d.HasChange("name") {
|
||||
err := resourceImageEditName(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -241,7 +270,7 @@ func ResourceImage() *schema.Resource {
|
||||
|
||||
CreateContext: resourceImageCreate,
|
||||
ReadContext: resourceImageRead,
|
||||
UpdateContext: resourceImageEdit,
|
||||
UpdateContext: resourceImageUpdate,
|
||||
DeleteContext: resourceImageDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -39,6 +39,8 @@ const (
|
||||
K8sDeleteAPI = "/restmachine/cloudapi/k8s/delete"
|
||||
K8sListAPI = "/restmachine/cloudapi/k8s/list"
|
||||
K8sListDeletedAPI = "/restmachine/cloudapi/k8s/listDeleted"
|
||||
K8sRestoreAPI = "/restmachine/cloudapi/k8s/restore"
|
||||
K8sEnableAPI = "/restmachine/cloudapi/k8s/enable"
|
||||
|
||||
K8sWgCreateAPI = "/restmachine/cloudapi/k8s/workersGroupAdd"
|
||||
K8sWgDeleteAPI = "/restmachine/cloudapi/k8s/workersGroupDelete"
|
||||
|
||||
@@ -38,51 +38,21 @@ 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/service/cloudapi/kvmvm"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func dataSourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("dataSourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
k8s, err := utilityDataK8sCheckPresence(ctx, d, m)
|
||||
wg, workersComputeList, err := utilityDataK8sWgCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(d.Get("wg_id").(int)))
|
||||
|
||||
var id int
|
||||
if d.Id() != "" {
|
||||
id, err = strconv.Atoi(d.Id())
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
id = d.Get("wg_id").(int)
|
||||
}
|
||||
|
||||
curWg := K8SGroup{}
|
||||
for _, wg := range k8s.K8SGroups.Workers {
|
||||
if wg.ID == uint64(id) {
|
||||
curWg = wg
|
||||
break
|
||||
}
|
||||
}
|
||||
if curWg.ID == 0 {
|
||||
return diag.Errorf("Not found wg with id: %v in k8s cluster: %v", id, k8s.ID)
|
||||
}
|
||||
|
||||
workersComputeList := make([]kvmvm.ComputeGetResp, 0, 0)
|
||||
for _, info := range curWg.DetailedInfo {
|
||||
compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
workersComputeList = append(workersComputeList, *compute)
|
||||
}
|
||||
|
||||
flattenWgData(d, curWg, workersComputeList)
|
||||
flattenWg(d, *wg, workersComputeList)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -257,9 +257,13 @@ func flattenK8sList(d *schema.ResourceData, k8sItems K8SList) {
|
||||
}
|
||||
|
||||
func flattenResourceK8s(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.ComputeGetResp, workers []kvmvm.ComputeGetResp) {
|
||||
wg_name := k8s.K8SGroups.Workers[0].Name
|
||||
|
||||
d.Set("acl", flattenAcl(k8s.ACL))
|
||||
d.Set("account_id", k8s.AccountID)
|
||||
d.Set("account_name", k8s.AccountName)
|
||||
d.Set("k8sci_id", k8s.CIID)
|
||||
d.Set("wg_name", wg_name)
|
||||
d.Set("bservice_id", k8s.BServiceID)
|
||||
d.Set("created_by", k8s.CreatedBy)
|
||||
d.Set("created_time", k8s.CreatedTime)
|
||||
@@ -268,7 +272,9 @@ func flattenResourceK8s(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.C
|
||||
d.Set("k8s_ci_name", k8s.K8CIName)
|
||||
d.Set("masters", flattenMasterGroup(k8s.K8SGroups.Masters, masters))
|
||||
d.Set("workers", flattenK8sGroup(k8s.K8SGroups.Workers, workers))
|
||||
d.Set("with_lb", k8s.LBID != 0)
|
||||
d.Set("lb_id", k8s.LBID)
|
||||
d.Set("name", k8s.Name)
|
||||
d.Set("rg_id", k8s.RGID)
|
||||
d.Set("rg_name", k8s.RGName)
|
||||
d.Set("status", k8s.Status)
|
||||
@@ -278,7 +284,7 @@ func flattenResourceK8s(d *schema.ResourceData, k8s K8SRecord, masters []kvmvm.C
|
||||
d.Set("default_wg_id", k8s.K8SGroups.Workers[0].ID)
|
||||
}
|
||||
|
||||
func flattenWgData(d *schema.ResourceData, wg K8SGroup, computes []kvmvm.ComputeGetResp) {
|
||||
func flattenWg(d *schema.ResourceData, wg K8SGroup, computes []kvmvm.ComputeGetResp) {
|
||||
d.Set("annotations", wg.Annotations)
|
||||
d.Set("cpu", wg.CPU)
|
||||
d.Set("detailed_info", flattenDetailedInfo(wg.DetailedInfo, computes))
|
||||
|
||||
143
internal/service/cloudapi/k8s/resource_check_input_values.go
Normal file
143
internal/service/cloudapi/k8s/resource_check_input_values.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func existK8sID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
k8sList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
k8sListAPI := "/restmachine/cloudapi/k8s/list"
|
||||
|
||||
k8sListRaw, err := c.DecortAPICall(ctx, "POST", k8sListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(k8sListRaw), &k8sList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveK8s := false
|
||||
k8sID := d.Get("k8s_id").(int)
|
||||
for _, k8s := range k8sList {
|
||||
if k8s.ID == k8sID {
|
||||
haveK8s = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveK8s, nil
|
||||
}
|
||||
|
||||
func existK8sCIID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
k8sciList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
k8sciListAPI := "/restmachine/cloudapi/k8ci/list"
|
||||
|
||||
k8sciListRaw, err := c.DecortAPICall(ctx, "POST", k8sciListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(k8sciListRaw), &k8sciList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveK8sCI := false
|
||||
k8sciID := d.Get("k8sci_id").(int)
|
||||
for _, k8ci := range k8sciList {
|
||||
if k8ci.ID == k8sciID {
|
||||
haveK8sCI = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveK8sCI, nil
|
||||
}
|
||||
|
||||
func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
rgList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
rgListAPI := "/restmachine/cloudapi/rg/list"
|
||||
|
||||
rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(rgListRaw), &rgList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveRG := false
|
||||
rgId := d.Get("rg_id").(int)
|
||||
for _, rg := range rgList {
|
||||
if rg.ID == rgId {
|
||||
haveRG = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveRG, nil
|
||||
}
|
||||
|
||||
func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
extNetID := d.Get("extnet_id").(int)
|
||||
|
||||
if extNetID == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
extNetList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
extNetListAPI := "/restmachine/cloudapi/extnet/list"
|
||||
|
||||
extNetListRaw, err := c.DecortAPICall(ctx, "POST", extNetListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(extNetListRaw), &extNetList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveExtNet := false
|
||||
for _, extNet := range extNetList {
|
||||
if extNet.ID == extNetID {
|
||||
haveExtNet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveExtNet, nil
|
||||
}
|
||||
@@ -43,15 +43,45 @@ import (
|
||||
|
||||
"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/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
)
|
||||
|
||||
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))
|
||||
|
||||
haveRGID, err := existRGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveRGID {
|
||||
return diag.Errorf("resourceK8sCreate: can't create k8s cluster because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
|
||||
haveK8sciID, err := existK8sCIID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveK8sciID {
|
||||
return diag.Errorf("resourceK8sCreate: can't create k8s cluster because K8sCIID %d is not allowed or does not exist", d.Get("k8sci_id").(int))
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("extnet_id"); ok {
|
||||
haveExtNetID, err := existExtNetID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveExtNetID {
|
||||
return diag.Errorf("resourceK8sCreate: can't create k8s cluster because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
@@ -158,12 +188,61 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
}
|
||||
|
||||
func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
|
||||
k8s, err := utilityDataK8sCheckPresence(ctx, d, m)
|
||||
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
hasChanged := false
|
||||
|
||||
switch k8s.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", k8s.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Deleting:
|
||||
case status.Deleted:
|
||||
urlVal := &url.Values{}
|
||||
urlVal.Add("k8sId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", K8sRestoreAPI, urlVal)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", K8sEnableAPI, urlVal)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The k8s cluster is in progress with status: %s", k8s.Status)
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceK8sCreate(ctx, d, m)
|
||||
case status.Enabling:
|
||||
case status.Enabled:
|
||||
case status.Disabling:
|
||||
case status.Disabled:
|
||||
log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", k8s.Status)
|
||||
case status.Restoring:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
k8s, err = utilityK8sCheckPresence(ctx, d, m)
|
||||
if k8s == nil {
|
||||
d.SetId("")
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
k8sList, err := utilityK8sListCheckPresence(ctx, d, m, K8sListAPI)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
@@ -201,7 +280,6 @@ func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
|
||||
flattenResourceK8s(d, *k8s, masterComputeList, workersComputeList)
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("lbId", strconv.FormatUint(k8s.LBID, 10))
|
||||
|
||||
@@ -233,6 +311,76 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
haveRGID, err := existRGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveRGID {
|
||||
return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
|
||||
haveK8sciID, err := existK8sCIID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveK8sciID {
|
||||
return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because K8sCIID %d is not allowed or does not exist", d.Get("k8sci_id").(int))
|
||||
}
|
||||
|
||||
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged := false
|
||||
|
||||
switch k8s.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The k8s cluster is in status: %s, please, contact support for more information", k8s.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Deleting:
|
||||
case status.Deleted:
|
||||
urlVal := &url.Values{}
|
||||
urlVal.Add("k8sId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", K8sRestoreAPI, urlVal)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
_, err = c.DecortAPICall(ctx, "POST", K8sEnableAPI, urlVal)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The k8s cluster is in progress with status: %s", k8s.Status)
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceK8sCreate(ctx, d, m)
|
||||
case status.Enabling:
|
||||
case status.Enabled:
|
||||
case status.Disabling:
|
||||
case status.Disabled:
|
||||
log.Debugf("The k8s cluster is in status: %s, troubles may occur with update. Please, enable compute first.", k8s.Status)
|
||||
case status.Restoring:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
k8s, err = utilityK8sCheckPresence(ctx, d, m)
|
||||
if k8s == nil {
|
||||
d.SetId("")
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("name") {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
@@ -245,11 +393,6 @@ func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
}
|
||||
|
||||
if d.HasChange("workers") {
|
||||
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
wg := k8s.K8SGroups.Workers[0]
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
@@ -321,7 +464,6 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
|
||||
"wg_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Name for first worker group created with cluster.",
|
||||
},
|
||||
"labels": {
|
||||
@@ -369,7 +511,6 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
|
||||
"with_lb": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Default: true,
|
||||
Description: "Create k8s with load balancer if true.",
|
||||
},
|
||||
|
||||
@@ -40,15 +40,24 @@ import (
|
||||
|
||||
"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/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceK8sWgCreate: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
haveK8sID, err := existK8sID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveK8sID {
|
||||
return diag.Errorf("resourceK8sCreate: can't create k8s cluster because K8sID %d is not allowed or does not exist", d.Get("k8s_id").(int))
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
@@ -56,7 +65,12 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
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)))
|
||||
|
||||
if d.Get("disk") == nil {
|
||||
urlValues.Add("workerDisk", strconv.Itoa(0))
|
||||
} else {
|
||||
urlValues.Add("workerDisk", strconv.Itoa(d.Get("disk").(int)))
|
||||
}
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", K8sWgCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
@@ -100,34 +114,13 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceK8sWgRead: called with %v", d.Id())
|
||||
|
||||
k8s, err := utilityDataK8sCheckPresence(ctx, d, m)
|
||||
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
var id int
|
||||
if d.Id() != "" {
|
||||
id, err = strconv.Atoi(strings.Split(d.Id(), "#")[0])
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
id = d.Get("wg_id").(int)
|
||||
}
|
||||
|
||||
curWg := K8SGroup{}
|
||||
for _, wg := range k8s.K8SGroups.Workers {
|
||||
if wg.ID == uint64(id) {
|
||||
curWg = wg
|
||||
break
|
||||
}
|
||||
}
|
||||
if curWg.ID == 0 {
|
||||
return diag.Errorf("Not found wg with id: %v in k8s cluster: %v", id, k8s.ID)
|
||||
}
|
||||
|
||||
workersComputeList := make([]kvmvm.ComputeGetResp, 0, 0)
|
||||
for _, info := range curWg.DetailedInfo {
|
||||
for _, info := range wg.DetailedInfo {
|
||||
compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -135,10 +128,20 @@ func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{
|
||||
workersComputeList = append(workersComputeList, *compute)
|
||||
}
|
||||
|
||||
d.Set("wg_id", wg.ID)
|
||||
if strings.Contains(d.Id(), "#") {
|
||||
k8sId, err := strconv.Atoi(strings.Split(d.Id(), "#")[1])
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("k8s_id", k8sId)
|
||||
} else {
|
||||
d.Set("k8s_id", d.Get("k8s_id"))
|
||||
}
|
||||
d.SetId(strings.Split(d.Id(), "#")[0])
|
||||
d.Set("k8s_id", k8s.ID)
|
||||
d.Set("wg_id", curWg.ID)
|
||||
flattenWgData(d, curWg, workersComputeList)
|
||||
|
||||
flattenWg(d, *wg, workersComputeList)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -148,6 +151,15 @@ func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
haveK8sID, err := existK8sID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveK8sID {
|
||||
return diag.Errorf("resourceK8sUpdate: can't update k8s cluster because K8sID %d is not allowed or does not exist", d.Get("k8s_id").(int))
|
||||
}
|
||||
|
||||
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -242,8 +254,7 @@ func resourceK8sWgSchemaMake() map[string]*schema.Schema {
|
||||
"disk": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Default: 0,
|
||||
Computed: true,
|
||||
Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.",
|
||||
},
|
||||
"wg_id": {
|
||||
|
||||
@@ -37,7 +37,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
@@ -89,15 +88,8 @@ func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m
|
||||
func utilityDataK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8SRecord, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
if d.Get("k8s_id") != 0 && d.Get("k8s_id") != nil {
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
} else if id := d.Id(); id != "" {
|
||||
if strings.Contains(id, "#") {
|
||||
urlValues.Add("k8sId", strings.Split(d.Id(), "#")[1])
|
||||
} else {
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
}
|
||||
}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
|
||||
k8sRaw, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -38,15 +38,82 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/kvmvm"
|
||||
)
|
||||
|
||||
func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8SGroup, []kvmvm.ComputeGetResp, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
k8sId := d.Get("k8s_id").(int)
|
||||
wgId := d.Get("wg_id").(int)
|
||||
|
||||
urlValues.Add("k8sId", strconv.Itoa(k8sId))
|
||||
|
||||
k8sRaw, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k8s := K8SRecord{}
|
||||
err = json.Unmarshal([]byte(k8sRaw), &k8s)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
curWg := K8SGroup{}
|
||||
for _, wg := range k8s.K8SGroups.Workers {
|
||||
if wg.ID == uint64(wgId) {
|
||||
curWg = wg
|
||||
break
|
||||
}
|
||||
}
|
||||
if curWg.ID == 0 {
|
||||
return nil, nil, fmt.Errorf("WG with id %v in k8s cluster %v not found", wgId, k8sId)
|
||||
}
|
||||
|
||||
workersComputeList := make([]kvmvm.ComputeGetResp, 0, 0)
|
||||
for _, info := range curWg.DetailedInfo {
|
||||
compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
workersComputeList = append(workersComputeList, *compute)
|
||||
}
|
||||
|
||||
return &curWg, workersComputeList, nil
|
||||
}
|
||||
|
||||
func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8SGroup, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
var wgId int
|
||||
var k8sId int
|
||||
var err error
|
||||
|
||||
if strings.Contains(d.Id(), "#") {
|
||||
wgId, err = strconv.Atoi(strings.Split(d.Id(), "#")[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k8sId, err = strconv.Atoi(strings.Split(d.Id(), "#")[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
wgId, err = strconv.Atoi(d.Id())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k8sId = d.Get("k8s_id").(int)
|
||||
}
|
||||
|
||||
urlValues.Add("k8sId", strconv.Itoa(k8sId))
|
||||
|
||||
resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues)
|
||||
if err != nil {
|
||||
@@ -62,21 +129,11 @@ func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m in
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var id int
|
||||
if d.Id() != "" {
|
||||
id, err = strconv.Atoi(d.Id())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
id = d.Get("wg_id").(int)
|
||||
}
|
||||
|
||||
for _, wg := range k8s.K8SGroups.Workers {
|
||||
if wg.ID == uint64(id) {
|
||||
if wg.ID == uint64(wgId) {
|
||||
return &wg, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Not found wg with id: %v in k8s cluster: %v", id, k8s.ID)
|
||||
return nil, fmt.Errorf("Not found wg with id: %v in k8s cluster: %v", wgId, k8s.ID)
|
||||
}
|
||||
|
||||
@@ -82,8 +82,8 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
urlValues.Add("netType", "NONE")
|
||||
urlValues.Add("start", "0") // at the 1st step create compute in a stopped state
|
||||
|
||||
argVal, argSet := d.GetOk("description")
|
||||
if argSet {
|
||||
argVal, ok := d.GetOk("description")
|
||||
if ok {
|
||||
urlValues.Add("desc", argVal.(string))
|
||||
}
|
||||
|
||||
@@ -138,8 +138,8 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("cloud_init")
|
||||
if argSet {
|
||||
argVal, ok = d.GetOk("cloud_init")
|
||||
if ok {
|
||||
// userdata must not be empty string and must not be a reserved keyword "applied"
|
||||
userdata := argVal.(string)
|
||||
if userdata != "" && userdata != "applied" {
|
||||
@@ -177,8 +177,8 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
|
||||
log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", compId, d.Get("name").(string))
|
||||
|
||||
argVal, argSet = d.GetOk("extra_disks")
|
||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||
argVal, ok = d.GetOk("extra_disks")
|
||||
if ok && argVal.(*schema.Set).Len() > 0 {
|
||||
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
|
||||
if err != nil {
|
||||
@@ -187,8 +187,8 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
argVal, argSet = d.GetOk("network")
|
||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||
argVal, ok = d.GetOk("network")
|
||||
if ok && 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, true)
|
||||
if err != nil {
|
||||
@@ -447,6 +447,8 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged := false
|
||||
|
||||
switch compute.Status {
|
||||
case status.Deleted:
|
||||
urlValues := &url.Values{}
|
||||
@@ -459,22 +461,27 @@ func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceComputeCreate(ctx, d, m)
|
||||
case status.Disabled:
|
||||
log.Debugf("The compute is in status: %s, may troubles can be occured with update. Please, enable compute first.", compute.Status)
|
||||
log.Debugf("The compute is in status: %s, troubles may occur with update. Please, enable compute first.", compute.Status)
|
||||
case status.Redeploying:
|
||||
case status.Deleting:
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The compute is in progress with status: %s", compute.Status)
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The compute is in status: %s, please, contant the support for more information", compute.Status)
|
||||
return diag.Errorf("The compute is in status: %s, please, contact support for more information", compute.Status)
|
||||
}
|
||||
|
||||
compute, err = utilityComputeCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
if hasChanged {
|
||||
compute, err = utilityComputeCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = flattenCompute(d, compute); err != nil {
|
||||
|
||||
139
internal/service/cloudapi/lb/resource_check_input_values.go
Normal file
139
internal/service/cloudapi/lb/resource_check_input_values.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package lb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func existLBID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
lbList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
lbListAPI := "/restmachine/cloudapi/lb/list"
|
||||
|
||||
lbListRaw, err := c.DecortAPICall(ctx, "POST", lbListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(lbListRaw), &lbList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveLB := false
|
||||
lbId := d.Get("lb_id").(int)
|
||||
|
||||
for _, lb := range lbList {
|
||||
if lb.ID == lbId {
|
||||
haveLB = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveLB, nil
|
||||
}
|
||||
|
||||
func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
rgList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
rgListAPI := "/restmachine/cloudapi/rg/list"
|
||||
|
||||
rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(rgListRaw), &rgList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveRG := false
|
||||
rgId := d.Get("rg_id").(int)
|
||||
for _, rg := range rgList {
|
||||
if rg.ID == rgId {
|
||||
haveRG = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveRG, nil
|
||||
}
|
||||
|
||||
func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
extNetList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
extNetListAPI := "/restmachine/cloudapi/extnet/list"
|
||||
|
||||
extNetListRaw, err := c.DecortAPICall(ctx, "POST", extNetListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(extNetListRaw), &extNetList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveExtNet := false
|
||||
extNetID := d.Get("extnet_id").(int)
|
||||
for _, extNet := range extNetList {
|
||||
if extNet.ID == extNetID {
|
||||
haveExtNet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveExtNet, nil
|
||||
}
|
||||
|
||||
func existViNSID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
vinsList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
vinsListAPI := "/restmachine/cloudapi/vins/list"
|
||||
|
||||
vinsListRaw, err := c.DecortAPICall(ctx, "POST", vinsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(vinsListRaw), &vinsList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveVins := false
|
||||
vinsID := d.Get("vins_id").(int)
|
||||
for _, vins := range vinsList {
|
||||
if vins.ID == vinsID {
|
||||
haveVins = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveVins, nil
|
||||
}
|
||||
@@ -42,11 +42,39 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"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/status"
|
||||
)
|
||||
|
||||
func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBCreate")
|
||||
|
||||
haveRGID, err := existRGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveRGID {
|
||||
return diag.Errorf("resourceLBCreate: can't create LB because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
|
||||
haveExtNetID, err := existExtNetID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveExtNetID {
|
||||
return diag.Errorf("resourceLBCreate: can't create LB because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int))
|
||||
}
|
||||
|
||||
haveVins, err := existViNSID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveVins {
|
||||
return diag.Errorf("resourceLBCreate: can't create LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int))
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
@@ -100,12 +128,57 @@ func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}
|
||||
func resourceLBRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBRead")
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
lb, err := utilityLBCheckPresence(ctx, d, m)
|
||||
if lb == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged := false
|
||||
|
||||
switch lb.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The LB is in status: %s, please, contact support for more information", lb.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Deleting:
|
||||
case status.Deleted:
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("lbId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbRestoreAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbEnableAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The LB is in progress with status: %s", lb.Status)
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceLBCreate(ctx, d, m)
|
||||
case status.Enabled:
|
||||
case status.Enabling:
|
||||
case status.Disabling:
|
||||
case status.Disabled:
|
||||
log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lb.Status)
|
||||
case status.Restoring:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
lb, err = utilityLBCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
d.Set("ha_mode", lb.HAMode)
|
||||
d.Set("backends", flattenLBBackends(lb.Backends))
|
||||
d.Set("created_by", lb.CreatedBy)
|
||||
@@ -163,11 +236,87 @@ func resourceLBDelete(ctx context.Context, d *schema.ResourceData, m interface{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceLBEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBEdit")
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
haveRGID, err := existRGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveRGID {
|
||||
return diag.Errorf("resourceLBUpdate: can't update LB because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
|
||||
haveExtNetID, err := existExtNetID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveExtNetID {
|
||||
return diag.Errorf("resourceLBUpdate: can't update LB because ExtNetID %d is not allowed or does not exist", d.Get("extnet_id").(int))
|
||||
}
|
||||
|
||||
haveVins, err := existViNSID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveVins {
|
||||
return diag.Errorf("resourceLBUpdate: can't update LB because ViNSID %d is not allowed or does not exist", d.Get("vins_id").(int))
|
||||
}
|
||||
|
||||
lb, err := utilityLBCheckPresence(ctx, d, m)
|
||||
if lb == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged := false
|
||||
|
||||
switch lb.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The LB is in status: %s, please, contact support for more information", lb.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Deleting:
|
||||
case status.Deleted:
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("lbId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbRestoreAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbEnableAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Destroying:
|
||||
return diag.Errorf("The LB is in progress with status: %s", lb.Status)
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceLBCreate(ctx, d, m)
|
||||
case status.Enabled:
|
||||
case status.Enabling:
|
||||
case status.Disabling:
|
||||
case status.Disabled:
|
||||
log.Debugf("The LB is in status: %s, troubles may occur with update. Please, enable LB first.", lb.Status)
|
||||
case status.Restoring:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
lb, err = utilityLBCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("enable") {
|
||||
api := lbDisableAPI
|
||||
enable := d.Get("enable").(bool)
|
||||
@@ -262,7 +411,7 @@ func ResourceLB() *schema.Resource {
|
||||
|
||||
CreateContext: resourceLBCreate,
|
||||
ReadContext: resourceLBRead,
|
||||
UpdateContext: resourceLBEdit,
|
||||
UpdateContext: resourceLBUpdate,
|
||||
DeleteContext: resourceLBDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -49,6 +49,15 @@ import (
|
||||
func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBBackendCreate")
|
||||
|
||||
haveLBID, err := existLBID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveLBID {
|
||||
return diag.Errorf("resourceLBBackendCreate: can't create LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("backendName", d.Get("name").(string))
|
||||
@@ -82,7 +91,7 @@ func resourceLBBackendCreate(ctx context.Context, d *schema.ResourceData, m inte
|
||||
urlValues.Add("weight", strconv.Itoa(weight.(int)))
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbBackendCreateAPI, urlValues)
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbBackendCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -155,11 +164,20 @@ func resourceLBBackendDelete(ctx context.Context, d *schema.ResourceData, m inte
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceLBBackendEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceLBBackendUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBBackendEdit")
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
haveLBID, err := existLBID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveLBID {
|
||||
return diag.Errorf("resourceLBBackendUpdate: can't update LB backend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
|
||||
}
|
||||
|
||||
urlValues.Add("backendName", d.Get("name").(string))
|
||||
urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int)))
|
||||
|
||||
@@ -191,7 +209,7 @@ func resourceLBBackendEdit(ctx context.Context, d *schema.ResourceData, m interf
|
||||
urlValues.Add("weight", strconv.Itoa(d.Get("weight").(int)))
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbBackendUpdateAPI, urlValues)
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbBackendUpdateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -207,7 +225,7 @@ func ResourceLBBackend() *schema.Resource {
|
||||
|
||||
CreateContext: resourceLBBackendCreate,
|
||||
ReadContext: resourceLBBackendRead,
|
||||
UpdateContext: resourceLBBackendEdit,
|
||||
UpdateContext: resourceLBBackendUpdate,
|
||||
DeleteContext: resourceLBBackendDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -49,6 +49,15 @@ import (
|
||||
func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBBackendServerCreate")
|
||||
|
||||
haveLBID, err := existLBID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveLBID {
|
||||
return diag.Errorf("resourceLBBackendServerCreate: can't create LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("backendName", d.Get("backend_name").(string))
|
||||
@@ -86,7 +95,7 @@ func resourceLBBackendServerCreate(ctx context.Context, d *schema.ResourceData,
|
||||
urlValues.Add("weight", strconv.Itoa(weight.(int)))
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbBackendServerAddAPI, urlValues)
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbBackendServerAddAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -163,11 +172,20 @@ func resourceLBBackendServerDelete(ctx context.Context, d *schema.ResourceData,
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceLBBackendServerEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceLBBackendServerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBBackendServerEdit")
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
haveLBID, err := existLBID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveLBID {
|
||||
return diag.Errorf("resourceLBBackendServerUpdate: can't update LB backend server because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
|
||||
}
|
||||
|
||||
urlValues.Add("backendName", d.Get("backend_name").(string))
|
||||
urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int)))
|
||||
urlValues.Add("serverName", d.Get("name").(string))
|
||||
@@ -202,7 +220,7 @@ func resourceLBBackendServerEdit(ctx context.Context, d *schema.ResourceData, m
|
||||
urlValues.Add("weight", strconv.Itoa(d.Get("weight").(int)))
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbBackendServerUpdateAPI, urlValues)
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbBackendServerUpdateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -218,7 +236,7 @@ func ResourceLBBackendServer() *schema.Resource {
|
||||
|
||||
CreateContext: resourceLBBackendServerCreate,
|
||||
ReadContext: resourceLBBackendServerRead,
|
||||
UpdateContext: resourceLBBackendServerEdit,
|
||||
UpdateContext: resourceLBBackendServerUpdate,
|
||||
DeleteContext: resourceLBBackendServerDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -48,13 +48,22 @@ import (
|
||||
func resourceLBFrontendCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBFrontendCreate")
|
||||
|
||||
haveLBID, err := existLBID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveLBID {
|
||||
return diag.Errorf("resourceLBFrontendCreate: can't create LB frontend because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("backendName", d.Get("backend_name").(string))
|
||||
urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int)))
|
||||
urlValues.Add("frontendName", d.Get("name").(string))
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbFrontendCreateAPI, urlValues)
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbFrontendCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
@@ -48,6 +48,15 @@ import (
|
||||
func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBFrontendBindCreate")
|
||||
|
||||
haveLBID, err := existLBID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveLBID {
|
||||
return diag.Errorf("resourceLBFrontendBindCreate: can't create LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("frontendName", d.Get("frontend_name").(string))
|
||||
@@ -56,7 +65,7 @@ func resourceLBFrontendBindCreate(ctx context.Context, d *schema.ResourceData, m
|
||||
urlValues.Add("bindingAddress", d.Get("address").(string))
|
||||
urlValues.Add("bindingPort", strconv.Itoa(d.Get("port").(int)))
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbFrontendBindAPI, urlValues)
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbFrontendBindAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -124,11 +133,20 @@ func resourceLBFrontendBindDelete(ctx context.Context, d *schema.ResourceData, m
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceLBFrontendBindEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceLBFrontendBindUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceLBFrontendBindEdit")
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
haveLBID, err := existLBID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveLBID {
|
||||
return diag.Errorf("resourceLBFrontendBindUpdate: can't update LB frontend bind because LBID %d is not allowed or does not exist", d.Get("lb_id").(int))
|
||||
}
|
||||
|
||||
urlValues.Add("frontendName", d.Get("frontend_name").(string))
|
||||
urlValues.Add("bindingName", d.Get("name").(string))
|
||||
urlValues.Add("lbId", strconv.Itoa(d.Get("lb_id").(int)))
|
||||
@@ -141,7 +159,7 @@ func resourceLBFrontendBindEdit(ctx context.Context, d *schema.ResourceData, m i
|
||||
urlValues.Add("bindingPort", strconv.Itoa(d.Get("port").(int)))
|
||||
}
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", lbFrontendBindUpdateAPI, urlValues)
|
||||
_, err = c.DecortAPICall(ctx, "POST", lbFrontendBindUpdateAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -155,7 +173,7 @@ func ResourceLBFrontendBind() *schema.Resource {
|
||||
|
||||
CreateContext: resourceLBFrontendBindCreate,
|
||||
ReadContext: resourceLBFrontendBindRead,
|
||||
UpdateContext: resourceLBFrontendBindEdit,
|
||||
UpdateContext: resourceLBFrontendBindUpdate,
|
||||
DeleteContext: resourceLBFrontendBindDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
|
||||
@@ -74,6 +74,7 @@ func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
}
|
||||
return haveAccount, nil
|
||||
}
|
||||
|
||||
func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
@@ -107,6 +108,7 @@ func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool,
|
||||
|
||||
return haveGID, nil
|
||||
}
|
||||
|
||||
func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
|
||||
@@ -52,13 +52,8 @@ 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
|
||||
|
||||
rgName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
rgName, ok := d.GetOk("name")
|
||||
if !ok {
|
||||
return diag.FromErr(fmt.Errorf("Cannot create new RG: missing name."))
|
||||
}
|
||||
|
||||
@@ -76,43 +71,39 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
}
|
||||
*/
|
||||
|
||||
// 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",
|
||||
rgName.(string), d.Get("account_id").(int))
|
||||
|
||||
// Check input values
|
||||
// AccountID
|
||||
haveAccount, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if !haveAccount {
|
||||
return diag.Errorf("resourceResgroupCreate: can't create RG bacause AccountID %d not allowed or does not exist", d.Get("account_id").(int))
|
||||
return diag.Errorf("resourceResgroupCreate: can't create RG because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
// GID
|
||||
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceResgroupCreate: can't create RG bacause GID %d not allowed or does not exist", d.Get("gid").(int))
|
||||
return diag.Errorf("resourceResgroupCreate: can't create RG because GID %d is not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
// ExtNetID
|
||||
|
||||
if _, ok := d.GetOk("ext_net_id"); ok {
|
||||
haveExtNet, err := existExtNetID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
if !haveExtNet {
|
||||
return diag.Errorf("resourceResgroupCreate: can't create RG bacause ExtNetID %d not allowed or does not exist", d.Get("ext_net_id").(int))
|
||||
return diag.Errorf("resourceResgroupCreate: can't create RG because ExtNetID %d is not allowed or does not exist", d.Get("ext_net_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
// quota settings are optional
|
||||
setQuota := false
|
||||
var quotaRecord QuotaRecord
|
||||
argValue, argSet := d.GetOk("quota")
|
||||
if argSet {
|
||||
argValue, ok := d.GetOk("quota")
|
||||
if ok {
|
||||
log.Debugf("resourceResgroupCreate: setting Quota on RG requested")
|
||||
quotaRecord = makeQuotaRecord(argValue.([]interface{}))
|
||||
setQuota = true
|
||||
@@ -125,53 +116,51 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
urlValues = &url.Values{}
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("name", rgName.(string))
|
||||
urlValues.Add("gid", strconv.Itoa(location.DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention
|
||||
urlValues.Add("gid", strconv.Itoa(location.DefaultGridID))
|
||||
urlValues.Add("owner", c.GetDecortUsername())
|
||||
|
||||
// pass quota values as set
|
||||
if setQuota {
|
||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(quotaRecord.Cpu))
|
||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(quotaRecord.Disk))
|
||||
urlValues.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotaRecord.Ram)) // RAM quota is float; this may change in the future
|
||||
urlValues.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotaRecord.Ram))
|
||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(quotaRecord.ExtTraffic))
|
||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(quotaRecord.ExtIPs))
|
||||
}
|
||||
|
||||
// parse and handle network settings
|
||||
defNetType, argSet := d.GetOk("def_net_type")
|
||||
if argSet {
|
||||
defNetType, ok := d.GetOk("def_net_type")
|
||||
if ok {
|
||||
urlValues.Add("def_net", defNetType.(string)) // NOTE: in API default network type is set by "def_net" parameter
|
||||
} else {
|
||||
d.Set("def_net_type", "PRIVATE")
|
||||
}
|
||||
|
||||
ipcidr, argSet := d.GetOk("ipcidr")
|
||||
if argSet {
|
||||
ipcidr, ok := d.GetOk("ipcidr")
|
||||
if ok {
|
||||
urlValues.Add("ipcidr", ipcidr.(string))
|
||||
}
|
||||
|
||||
description, argSet := d.GetOk("description")
|
||||
if argSet {
|
||||
description, ok := d.GetOk("description")
|
||||
if ok {
|
||||
urlValues.Add("desc", description.(string))
|
||||
}
|
||||
|
||||
reason, argSet := d.GetOk("reason")
|
||||
if argSet {
|
||||
reason, ok := d.GetOk("reason")
|
||||
if ok {
|
||||
urlValues.Add("reason", reason.(string))
|
||||
}
|
||||
|
||||
extNetId, argSet := d.GetOk("ext_net_id")
|
||||
if argSet {
|
||||
extNetId, ok := d.GetOk("ext_net_id")
|
||||
if ok {
|
||||
urlValues.Add("extNetId", strconv.Itoa(extNetId.(int)))
|
||||
}
|
||||
|
||||
extIp, argSet := d.GetOk("ext_ip")
|
||||
if argSet {
|
||||
extIp, ok := d.GetOk("ext_ip")
|
||||
if ok {
|
||||
urlValues.Add("extIp", extIp.(string))
|
||||
}
|
||||
|
||||
regComputes, argSet := d.GetOk("register_computes")
|
||||
if argSet {
|
||||
regComputes, ok := d.GetOk("register_computes")
|
||||
if ok {
|
||||
urlValues.Add("registerComputes", strconv.FormatBool(regComputes.(bool)))
|
||||
}
|
||||
|
||||
@@ -179,7 +168,8 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
d.SetId(apiResp) // rg/create API returns ID of the newly creted resource group on success
|
||||
|
||||
d.SetId(apiResp)
|
||||
|
||||
w := dc.Warnings{}
|
||||
if access, ok := d.GetOk("access"); ok {
|
||||
@@ -257,7 +247,6 @@ func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
}
|
||||
}
|
||||
|
||||
// re-read newly created RG to make sure schema contains complete and up to date set of specifications
|
||||
defer resourceResgroupRead(ctx, d, m)
|
||||
return w.Get()
|
||||
}
|
||||
@@ -268,23 +257,34 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
rgFacts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
rg, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("") // ensure ID is empty
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
switch rgFacts.Status {
|
||||
hasChanged := false
|
||||
|
||||
switch rg.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The resource group is in status: %s, please, contact support for more information", rg.Status)
|
||||
case status.Created:
|
||||
case status.Enabled:
|
||||
case status.Deleted:
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("rgId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", RgRestoreAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
_, err = c.DecortAPICall(ctx, "POST", RgEnableAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
|
||||
case status.Deleting:
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
@@ -296,12 +296,14 @@ func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interfa
|
||||
case status.Enabling:
|
||||
}
|
||||
|
||||
rgFacts, err = utilityResgroupCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("") // ensure ID is empty
|
||||
return diag.FromErr(err)
|
||||
if hasChanged {
|
||||
rg, err = utilityResgroupCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
return diag.FromErr(flattenResgroup(d, *rgFacts))
|
||||
return diag.FromErr(flattenResgroup(d, *rg))
|
||||
}
|
||||
|
||||
func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -311,8 +313,6 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
// Check input values
|
||||
// AccountID
|
||||
haveAccount, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -320,7 +320,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
if !haveAccount {
|
||||
return diag.Errorf("resourceResgroupUpdate: can't create RG bacause AccountID %d not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
// GID
|
||||
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -328,7 +328,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceResgroupUpdate: can't create RG bacause GID %d not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
// ExtNetID
|
||||
|
||||
if _, ok := d.GetOk("ext_net_id"); ok {
|
||||
haveExtNet, err := existExtNetID(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -341,10 +341,12 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
|
||||
rgFacts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("") // ensure ID is empty
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged := false
|
||||
|
||||
switch rgFacts.Status {
|
||||
case status.Modeled:
|
||||
case status.Created:
|
||||
@@ -356,6 +358,12 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
_, err = c.DecortAPICall(ctx, "POST", RgEnableAPI, urlValues)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
hasChanged = true
|
||||
case status.Deleting:
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
@@ -366,6 +374,14 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
case status.Enabled:
|
||||
case status.Enabling:
|
||||
}
|
||||
|
||||
if hasChanged {
|
||||
rgFacts, err = utilityDataResgroupCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
/* NOTE: we do not allow changing the following attributes of an existing RG via terraform:
|
||||
- def_net_type
|
||||
- ipcidr
|
||||
@@ -393,7 +409,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing ext_net_id for existing RG is not allowed", d.Id()))
|
||||
}
|
||||
|
||||
doGeneralUpdate := false // will be true if general RG update is necessary (API rg/update)
|
||||
doGeneralUpdate := false
|
||||
|
||||
urlValues = &url.Values{}
|
||||
urlValues.Add("rgId", d.Id())
|
||||
@@ -412,7 +428,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
if quotaSet {
|
||||
log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.")
|
||||
quotarecordNew := makeQuotaRecord(quotaValue.([]interface{}))
|
||||
quotaValueOld, _ := d.GetChange("quota") // returns old as 1st, new as 2nd return value
|
||||
quotaValueOld, _ := d.GetChange("quota")
|
||||
quotarecordOld := makeQuotaRecord(quotaValueOld.([]interface{}))
|
||||
log.Debug(quotaValueOld, quotarecordNew)
|
||||
|
||||
@@ -428,7 +444,7 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(quotarecordNew.Disk))
|
||||
}
|
||||
|
||||
if quotarecordNew.Ram != quotarecordOld.Ram { // NB: quota on RAM is stored as float32, in units of MB
|
||||
if quotarecordNew.Ram != quotarecordOld.Ram {
|
||||
doGeneralUpdate = true
|
||||
log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecordNew.Ram, quotarecordOld.Ram)
|
||||
urlValues.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecordNew.Ram))
|
||||
@@ -605,7 +621,7 @@ func ResourceRgSchemaMake() map[string]*schema.Schema {
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true, // change of Grid ID will require new RG
|
||||
ForceNew: true,
|
||||
Description: "Unique ID of the grid, where this resource group is deployed.",
|
||||
},
|
||||
|
||||
@@ -816,7 +832,7 @@ func ResourceRgSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
},
|
||||
"vins": {
|
||||
Type: schema.TypeList, //this is a list of ints
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
@@ -825,7 +841,7 @@ func ResourceRgSchemaMake() map[string]*schema.Schema {
|
||||
},
|
||||
|
||||
"vms": {
|
||||
Type: schema.TypeList, //t his is a list of ints
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
|
||||
146
internal/service/cloudapi/vins/resource_check_input_values.go
Normal file
146
internal/service/cloudapi/vins/resource_check_input_values.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package vins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func existRGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
rgList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
rgListAPI := "/restmachine/cloudapi/rg/list"
|
||||
|
||||
rgListRaw, err := c.DecortAPICall(ctx, "POST", rgListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(rgListRaw), &rgList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveRG := false
|
||||
rgId := d.Get("rg_id").(int)
|
||||
for _, rg := range rgList {
|
||||
if rg.ID == rgId {
|
||||
haveRG = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveRG, nil
|
||||
}
|
||||
|
||||
func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
extNetID := d.Get("ext_net_id").(int)
|
||||
|
||||
if extNetID == 0 || extNetID == -1 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
extNetList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
extNetListAPI := "/restmachine/cloudapi/extnet/list"
|
||||
|
||||
extNetListRaw, err := c.DecortAPICall(ctx, "POST", extNetListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(extNetListRaw), &extNetList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveExtNet := false
|
||||
for _, extNet := range extNetList {
|
||||
if extNet.ID == extNetID {
|
||||
haveExtNet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveExtNet, nil
|
||||
}
|
||||
|
||||
func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
|
||||
accountList := []struct {
|
||||
ID int `json:"id"`
|
||||
}{}
|
||||
|
||||
accountListAPI := "/restmachine/cloudapi/account/list"
|
||||
|
||||
accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(accountListRaw), &accountList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveAccount := false
|
||||
|
||||
myAccount := d.Get("account_id").(int)
|
||||
for _, account := range accountList {
|
||||
if account.ID == myAccount {
|
||||
haveAccount = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return haveAccount, nil
|
||||
}
|
||||
|
||||
func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
urlValues := &url.Values{}
|
||||
|
||||
locationList := []struct {
|
||||
GID int `json:"gid"`
|
||||
}{}
|
||||
|
||||
locationsListAPI := "/restmachine/cloudapi/locations/list"
|
||||
|
||||
locationListRaw, err := c.DecortAPICall(ctx, "POST", locationsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(locationListRaw), &locationList)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
haveGID := false
|
||||
|
||||
gid := d.Get("gid").(int)
|
||||
for _, location := range locationList {
|
||||
if location.GID == gid {
|
||||
haveGID = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return haveGID, nil
|
||||
}
|
||||
@@ -38,11 +38,11 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"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/dc"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -53,6 +53,50 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
if _, ok := d.GetOk("rg_id"); ok {
|
||||
haveRGID, err := existRGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveRGID {
|
||||
return diag.Errorf("resourceVinsCreate: can't create ViNS because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("ext_net_id"); ok {
|
||||
haveExtNetID, err := existExtNetID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveExtNetID {
|
||||
return diag.Errorf("resourceVinsCreate: can't create ViNS because ExtNetID %d is not allowed or does not exist", d.Get("ext_net_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("account_id"); ok {
|
||||
haveAccountID, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveAccountID {
|
||||
return diag.Errorf("resourceVinsCreate: can't create ViNS because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("gid"); ok {
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceVinsCreate: can't create ViNS because GID %d is not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
}
|
||||
|
||||
rgId, rgOk := d.GetOk("rg_id")
|
||||
accountId, accountIdOk := d.GetOk("account_id")
|
||||
if !rgOk && !accountIdOk {
|
||||
@@ -164,7 +208,6 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface
|
||||
|
||||
func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
vins, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
@@ -173,40 +216,58 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
isEnabled := d.Get("enable").(bool)
|
||||
|
||||
hasChangeState := false
|
||||
if vins.Status == status.Destroyed {
|
||||
|
||||
switch vins.Status {
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
d.Set("vins_id", 0)
|
||||
return resourceVinsCreate(ctx, d, m)
|
||||
} else if vins.Status == status.Deleted {
|
||||
case status.Deleted:
|
||||
hasChangeState = true
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsRestoreAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
urlValues = &url.Values{}
|
||||
case status.Modeled:
|
||||
return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vins.Status)
|
||||
case status.Created:
|
||||
case status.Enabled:
|
||||
if !isEnabled {
|
||||
hasChangeState = true
|
||||
urlValues := &url.Values{}
|
||||
|
||||
isEnabled := d.Get("enable").(bool)
|
||||
if vins.Status == status.Disabled && isEnabled {
|
||||
hasChangeState = true
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
} else if vins.Status == status.Enabled && !isEnabled {
|
||||
hasChangeState = true
|
||||
case status.Enabling:
|
||||
case status.Disabled:
|
||||
if isEnabled {
|
||||
hasChangeState = true
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
case status.Disabling:
|
||||
case status.Deleting:
|
||||
return diag.Errorf("ViNS are in progress with status: %s", vins.Status)
|
||||
}
|
||||
|
||||
if hasChangeState {
|
||||
vins, err = utilityVinsCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
@@ -216,6 +277,7 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}
|
||||
}
|
||||
|
||||
flattenVins(d, *vins)
|
||||
|
||||
return warnings.Get()
|
||||
}
|
||||
|
||||
@@ -245,18 +307,131 @@ func isContinsNatRule(els []interface{}, el interface{}) bool {
|
||||
|
||||
func resourceVinsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
if _, ok := d.GetOk("rg_id"); ok {
|
||||
haveRGID, err := existRGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveRGID {
|
||||
return diag.Errorf("resourceVinsUpdate: can't update ViNS because RGID %d is not allowed or does not exist", d.Get("rg_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("ext_net_id"); ok {
|
||||
haveExtNetID, err := existExtNetID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveExtNetID {
|
||||
return diag.Errorf("resourceVinsUpdate: can't update ViNS because ExtNetID %d is not allowed or does not exist", d.Get("ext_net_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("account_id"); ok {
|
||||
haveAccountID, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveAccountID {
|
||||
return diag.Errorf("resourceVinsUpdate: can't update ViNS because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("gid"); ok {
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceVinsUpdate: can't update ViNS because GID %d is not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
}
|
||||
|
||||
vins, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
isEnabled := d.Get("enable").(bool)
|
||||
|
||||
hasChangeState := false
|
||||
|
||||
switch vins.Status {
|
||||
case status.Destroyed:
|
||||
d.SetId("")
|
||||
return resourceVinsCreate(ctx, d, m)
|
||||
case status.Deleted:
|
||||
hasChangeState = true
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsRestoreAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
case status.Modeled:
|
||||
return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vins.Status)
|
||||
case status.Created:
|
||||
case status.Enabled:
|
||||
if !isEnabled {
|
||||
hasChangeState = true
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
case status.Enabling:
|
||||
case status.Disabled:
|
||||
if isEnabled {
|
||||
hasChangeState = true
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
case status.Disabling:
|
||||
case status.Deleting:
|
||||
return diag.Errorf("ViNS are in progress with status: %s", vins.Status)
|
||||
}
|
||||
|
||||
if hasChangeState {
|
||||
vins, err = utilityVinsCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
urlValues := &url.Values{}
|
||||
|
||||
enableOld, enableNew := d.GetChange("enable")
|
||||
if enableOld.(bool) && !enableNew.(bool) {
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
if !urlValues.Has("vinsId") {
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
}
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsDisableAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
} else if !enableOld.(bool) && enableNew.(bool) {
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
if !urlValues.Has("vinsId") {
|
||||
urlValues.Add("vinsId", d.Id())
|
||||
}
|
||||
_, err := c.DecortAPICall(ctx, "POST", VinsEnableAPI, urlValues)
|
||||
if err != nil {
|
||||
warnings.Add(err)
|
||||
@@ -532,6 +707,7 @@ func resourceVinsSchemaMake() map[string]*schema.Schema {
|
||||
}
|
||||
rets["rg_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
}
|
||||
rets["account_id"] = &schema.Schema{
|
||||
|
||||
@@ -38,9 +38,9 @@ import (
|
||||
|
||||
"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/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@@ -62,35 +62,6 @@ func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interfac
|
||||
|
||||
d.SetId(resp)
|
||||
|
||||
// This code is the supposed flow, but at the time of writing it's not yet implemented by the platfom
|
||||
|
||||
//urlValues = &url.Values{}
|
||||
//urlValues.Add("auditId", strings.Trim(resp, `"`))
|
||||
|
||||
//for {
|
||||
//resp, err := controller.decortAPICall("POST", AsyncTaskGetAPI, urlValues)
|
||||
//if err != nil {
|
||||
//return err
|
||||
//}
|
||||
|
||||
//task := AsyncTask{}
|
||||
//if err := json.Unmarshal([]byte(resp), &task); err != nil {
|
||||
//return err
|
||||
//}
|
||||
//log.Debugf("resourceK8sCreate: workers group creating - %s", task.Stage)
|
||||
|
||||
//if task.Completed {
|
||||
//if task.Error != "" {
|
||||
//return fmt.Errorf("cannot create workers group: %v", task.Error)
|
||||
//}
|
||||
|
||||
//d.SetId(strconv.Itoa(int(task.Result)))
|
||||
//break
|
||||
//}
|
||||
|
||||
//time.Sleep(time.Second * 5)
|
||||
//}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user