4.13.1
4.13.1
This commit is contained in:
@@ -1251,6 +1251,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"weight": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
|
||||
@@ -477,6 +477,10 @@ func itemComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"weight": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
@@ -564,6 +568,16 @@ func dataSourceComputeListSchemaMake() map[string]*schema.Schema {
|
||||
Optional: true,
|
||||
Description: "Zone ID",
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Find by VM folder ID",
|
||||
},
|
||||
"include_descendants": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Description: "Include computes from descendant folders",
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
|
||||
@@ -258,6 +258,7 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
|
||||
"hot_resize": compute.HotResize,
|
||||
"network_interface_naming": compute.NetworkInterfaceNaming,
|
||||
"zone_id": compute.ZoneID,
|
||||
"folder_id": compute.FolderID,
|
||||
"weight": compute.Weight,
|
||||
}
|
||||
res = append(res, temp)
|
||||
@@ -514,6 +515,7 @@ func flattenCompute(d *schema.ResourceData, computeRec compute.RecordCompute, pc
|
||||
d.Set("hot_resize", computeRec.HotResize)
|
||||
d.Set("network_interface_naming", computeRec.NetworkInterfaceNaming)
|
||||
d.Set("zone_id", computeRec.ZoneID)
|
||||
d.Set("folder_id", computeRec.FolderID)
|
||||
d.Set("loader_meta_iso", flattenLoaderMetaIso(computeRec.LoaderMetaIso))
|
||||
d.Set("cpu_pin", computeRec.CPUPin)
|
||||
d.Set("cpu_alignment_profile", computeRec.CPUAlignmentProfile.Name)
|
||||
@@ -817,6 +819,7 @@ func flattenDataCompute(d *schema.ResourceData, computeRec compute.RecordCompute
|
||||
d.Set("hot_resize", computeRec.HotResize)
|
||||
d.Set("network_interface_naming", computeRec.NetworkInterfaceNaming)
|
||||
d.Set("zone_id", computeRec.ZoneID)
|
||||
d.Set("folder_id", computeRec.FolderID)
|
||||
d.Set("loader_meta_iso", flattenLoaderMetaIso(computeRec.LoaderMetaIso))
|
||||
d.Set("os_version", computeRec.OSVersion)
|
||||
d.Set("cpu_alignment_profiles", flattenCPUAlignmentProfile(computeRec.CPUAlignmentProfile))
|
||||
|
||||
@@ -3029,6 +3029,10 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"vgpus": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
|
||||
@@ -89,6 +89,12 @@ func utilityDataComputeListCheckPresence(ctx context.Context, d *schema.Resource
|
||||
if zoneID, ok := d.GetOk("zone_id"); ok {
|
||||
req.ZoneID = uint64(zoneID.(int))
|
||||
}
|
||||
if folderID, ok := d.GetOk("folder_id"); ok {
|
||||
req.FolderID = uint64(folderID.(int))
|
||||
}
|
||||
if includeDescendants, ok := d.GetOkExists("include_descendants"); ok {
|
||||
req.IncludeDescendants = includeDescendants.(bool)
|
||||
}
|
||||
|
||||
listComputes, err := c.CloudAPI().Compute().List(ctx, req)
|
||||
if err != nil {
|
||||
|
||||
@@ -60,6 +60,7 @@ func flattenLocationsList(ll *locations.ListLocations) []map[string]interface{}
|
||||
"sdn_support": l.SDNSupport,
|
||||
"zero_access_enabled": l.ZeroAccessEnabled,
|
||||
"bro_enabled": l.BROEnabled,
|
||||
"vm_folders_enabled": l.VMFoldersEnabled,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
@@ -193,6 +194,10 @@ func dataSourceLocationsListSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"vm_folders_enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
130
internal/service/cloudapi/vmfolder/data_source_vm_folder.go
Normal file
130
internal/service/cloudapi/vmfolder/data_source_vm_folder.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
|
||||
)
|
||||
|
||||
func dataSourceVMFolderRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("dataSourceVMFolderRead: called with folder_id %d", d.Get("folder_id").(int))
|
||||
|
||||
w := dc.Warnings{}
|
||||
folder, err := utilityVMFolderCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
flattenVMFolder(d, folder)
|
||||
|
||||
return w.Get()
|
||||
}
|
||||
|
||||
func aclSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"explicit": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Whether the access is explicit",
|
||||
},
|
||||
"right": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Access rights",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Access status",
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Access type",
|
||||
},
|
||||
"user_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "User or group ID",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceVMFolderSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "ID of the vm folder",
|
||||
},
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the resource group",
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Grid ID",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the vm folder",
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: aclSchemaMake(),
|
||||
},
|
||||
Description: "Access control list of the vm folder",
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Time of creation",
|
||||
},
|
||||
"parent_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the parent vm folder",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Status of the vm folder",
|
||||
},
|
||||
"compute_ids": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of computes in the vm folder",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func DataSourceVMFolder() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceVMFolderRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceVMFolderSchemaMake(),
|
||||
}
|
||||
}
|
||||
108
internal/service/cloudapi/vmfolder/data_source_vm_folder_list.go
Normal file
108
internal/service/cloudapi/vmfolder/data_source_vm_folder_list.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/dc"
|
||||
)
|
||||
|
||||
func dataSourceVMFolderListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
w := dc.Warnings{}
|
||||
folderList, err := utilityVMFolderListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
|
||||
d.Set("items", flattenVMFolderList(folderList))
|
||||
d.Set("entry_count", folderList.EntryCount)
|
||||
|
||||
return w.Get()
|
||||
}
|
||||
|
||||
func dataSourceVMFolderListSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Find by resource group ID",
|
||||
},
|
||||
"page": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Page number",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Page size",
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the vm folder",
|
||||
},
|
||||
"parent_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the parent vm folder",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the vm folder",
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: aclSchemaMake(),
|
||||
},
|
||||
Description: "Access control list of the vm folder",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Status of the vm folder",
|
||||
},
|
||||
"vm_count": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Number of computes in the vm folder",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"entry_count": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func DataSourceVMFolderList() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceVMFolderListRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceVMFolderListSchemaMake(),
|
||||
}
|
||||
}
|
||||
54
internal/service/cloudapi/vmfolder/flattens.go
Normal file
54
internal/service/cloudapi/vmfolder/flattens.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vmfolder"
|
||||
)
|
||||
|
||||
func flattenVMFolder(d *schema.ResourceData, folder *vmfolder.RecordVMFolder) {
|
||||
log.Debugf("flattenVMFolder: decoded vm folder ID %d", folder.ID)
|
||||
|
||||
d.Set("folder_id", folder.ID)
|
||||
d.Set("rg_id", folder.RGID)
|
||||
d.Set("gid", folder.GID)
|
||||
d.Set("name", folder.Name)
|
||||
d.Set("acl", flattenVMFolderACL(folder.ACL))
|
||||
d.Set("created_time", folder.CreatedTime)
|
||||
d.Set("parent_id", folder.ParentID)
|
||||
d.Set("status", folder.Status)
|
||||
d.Set("compute_ids", folder.ComputeIDs)
|
||||
}
|
||||
|
||||
func flattenVMFolderACL(acl []vmfolder.ACL) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0, len(acl))
|
||||
for _, item := range acl {
|
||||
temp := map[string]interface{}{
|
||||
"explicit": item.Explicit,
|
||||
"right": item.Right,
|
||||
"status": item.Status,
|
||||
"type": item.Type,
|
||||
"user_group_id": item.UserGroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenVMFolderList(folderList *vmfolder.ListVMFolder) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0, len(folderList.Data))
|
||||
for _, item := range folderList.Data {
|
||||
temp := map[string]interface{}{
|
||||
"id": item.ID,
|
||||
"parent_id": item.ParentID,
|
||||
"name": item.Name,
|
||||
"acl": flattenVMFolderACL(item.ACL),
|
||||
"status": item.Status,
|
||||
"vm_count": item.VMCount,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
279
internal/service/cloudapi/vmfolder/resource_vm_folder.go
Normal file
279
internal/service/cloudapi/vmfolder/resource_vm_folder.go
Normal file
@@ -0,0 +1,279 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vmfolder"
|
||||
"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"
|
||||
)
|
||||
|
||||
func resourceVMFolderCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceVMFolderCreate: called with name %s, rg_id %d", d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
req := vmfolder.CreateRequest{
|
||||
RGID: uint64(d.Get("rg_id").(int)),
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
if parentID, ok := d.GetOk("parent_id"); ok {
|
||||
req.ParentID = uint64(parentID.(int))
|
||||
}
|
||||
|
||||
folderID, err := c.CloudAPI().VMFolder().Create(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(folderID, 10))
|
||||
d.Set("folder_id", folderID)
|
||||
|
||||
if aclAccess, ok := d.GetOk("acl_access"); ok {
|
||||
if err := utilityVMFolderACLAccessAdd(ctx, m, folderID, aclAccess.(*schema.Set).List()); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("computes_move"); ok {
|
||||
if err := utilityVMFolderComputesMove(ctx, d, m, folderID); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
return append(warnings.Get(), resourceVMFolderRead(ctx, d, m)...)
|
||||
}
|
||||
|
||||
func resourceVMFolderRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceVMFolderRead: called with id %s", d.Id())
|
||||
|
||||
w := dc.Warnings{}
|
||||
|
||||
folder, err := utilityVMFolderCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
flattenVMFolder(d, folder)
|
||||
|
||||
return w.Get()
|
||||
}
|
||||
|
||||
func resourceVMFolderUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceVMFolderUpdate: called with id %s", d.Id())
|
||||
|
||||
if d.HasChange("rg_id") {
|
||||
return diag.Errorf("resourceVMFolderUpdate: rg_id can't be changed")
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
folderID, err := strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if d.HasChange("name") {
|
||||
req := vmfolder.RenameRequest{
|
||||
FolderID: folderID,
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
if _, err := c.CloudAPI().VMFolder().Rename(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("parent_id") {
|
||||
req := vmfolder.MoveRequest{
|
||||
FolderID: folderID,
|
||||
NewParentID: uint64(d.Get("parent_id").(int)),
|
||||
}
|
||||
|
||||
if _, err := c.CloudAPI().VMFolder().Move(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("acl_access") {
|
||||
if err := utilityVMFolderACLAccessUpdate(ctx, d, m, folderID); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChanges("computes_move.#", "computes_move.0.compute_ids", "computes_move.0.folder_id") {
|
||||
if err := utilityVMFolderComputesMove(ctx, d, m, folderID); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
return resourceVMFolderRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceVMFolderDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceVMFolderDelete: called with id %s", d.Id())
|
||||
|
||||
folder, err := utilityVMFolderCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
req := vmfolder.DeleteRequest{
|
||||
FolderID: folder.ID,
|
||||
}
|
||||
|
||||
if _, err := c.CloudAPI().VMFolder().Delete(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceVMFolderSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "ID of the resource group",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the vm folder",
|
||||
},
|
||||
"parent_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the parent vm folder",
|
||||
},
|
||||
"computes_move": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_ids": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of computes to move",
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the target vm folder. If not set, computes are moved to this vm folder",
|
||||
},
|
||||
},
|
||||
},
|
||||
Description: "Move computes to the vm folder",
|
||||
},
|
||||
"acl_access": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"user": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "User or group name to grant access",
|
||||
},
|
||||
"right": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"R", "RCX", "ARCXDU"}, false),
|
||||
Description: "Access rights to set, one of 'R', 'RCX' or 'ARCXDU'",
|
||||
},
|
||||
},
|
||||
},
|
||||
Description: "ACL access rules for the vm folder",
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the vm folder",
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Grid ID",
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: aclSchemaMake(),
|
||||
},
|
||||
Description: "Access control list of the vm folder",
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Time of creation",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Status of the vm folder",
|
||||
},
|
||||
"compute_ids": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of computes in the vm folder",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ResourceVMFolder() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
|
||||
if diff.HasChange("acl_access") {
|
||||
diff.SetNewComputed("acl")
|
||||
}
|
||||
if diff.HasChanges("computes_move.#", "computes_move.0.compute_ids", "computes_move.0.folder_id") {
|
||||
diff.SetNewComputed("compute_ids")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
||||
CreateContext: resourceVMFolderCreate,
|
||||
ReadContext: resourceVMFolderRead,
|
||||
UpdateContext: resourceVMFolderUpdate,
|
||||
DeleteContext: resourceVMFolderDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout600s,
|
||||
Read: &constants.Timeout600s,
|
||||
Update: &constants.Timeout600s,
|
||||
Delete: &constants.Timeout600s,
|
||||
Default: &constants.Timeout600s,
|
||||
},
|
||||
|
||||
Schema: resourceVMFolderSchemaMake(),
|
||||
}
|
||||
}
|
||||
117
internal/service/cloudapi/vmfolder/utility_vm_folder.go
Normal file
117
internal/service/cloudapi/vmfolder/utility_vm_folder.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vmfolder"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityVMFolderCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vmfolder.RecordVMFolder, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := vmfolder.GetRequest{}
|
||||
|
||||
if d.Id() != "" {
|
||||
id, err := strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.FolderID = id
|
||||
} else {
|
||||
req.FolderID = uint64(d.Get("folder_id").(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderCheckPresence: get vm folder with ID %d", req.FolderID)
|
||||
|
||||
folder, err := c.CloudAPI().VMFolder().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return folder, nil
|
||||
}
|
||||
|
||||
func utilityVMFolderComputesMove(ctx context.Context, d *schema.ResourceData, m interface{}, folderID uint64) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
computesMove := d.Get("computes_move").([]interface{})
|
||||
if len(computesMove) == 0 || computesMove[0] == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
item := computesMove[0].(map[string]interface{})
|
||||
|
||||
computeIDs := make([]uint64, 0)
|
||||
for _, id := range item["compute_ids"].(*schema.Set).List() {
|
||||
computeIDs = append(computeIDs, uint64(id.(int)))
|
||||
}
|
||||
if len(computeIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
req := vmfolder.ComputesMoveRequest{
|
||||
ComputeIDs: computeIDs,
|
||||
FolderID: folderID,
|
||||
}
|
||||
if targetFolderID := item["folder_id"].(int); targetFolderID != 0 {
|
||||
req.FolderID = uint64(targetFolderID)
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderComputesMove: move computes %v to vm folder with ID %d", computeIDs, req.FolderID)
|
||||
|
||||
_, err := c.CloudAPI().VMFolder().ComputesMove(ctx, req)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func utilityVMFolderACLAccessAdd(ctx context.Context, m interface{}, folderID uint64, aclAccess []interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
for _, aclInterface := range aclAccess {
|
||||
aclItem := aclInterface.(map[string]interface{})
|
||||
|
||||
req := vmfolder.AddACLAccessRequest{
|
||||
FolderID: folderID,
|
||||
User: aclItem["user"].(string),
|
||||
Right: aclItem["right"].(string),
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderACLAccessAdd: add ACL access %s for user %s to vm folder with ID %d", req.Right, req.User, folderID)
|
||||
|
||||
if _, err := c.CloudAPI().VMFolder().AddACLAccess(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func utilityVMFolderACLAccessUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, folderID uint64) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
oldSet, newSet := d.GetChange("acl_access")
|
||||
|
||||
deletedAccess := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List()
|
||||
for _, deletedInterface := range deletedAccess {
|
||||
deletedItem := deletedInterface.(map[string]interface{})
|
||||
|
||||
req := vmfolder.DelACLAccessRequest{
|
||||
FolderID: folderID,
|
||||
User: deletedItem["user"].(string),
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderACLAccessUpdate: delete ACL access for user %s from vm folder with ID %d", req.User, folderID)
|
||||
|
||||
if _, err := c.CloudAPI().VMFolder().DeleteACLAccess(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
addedAccess := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List()
|
||||
|
||||
return utilityVMFolderACLAccessAdd(ctx, m, folderID, addedAccess)
|
||||
}
|
||||
33
internal/service/cloudapi/vmfolder/utility_vm_folder_list.go
Normal file
33
internal/service/cloudapi/vmfolder/utility_vm_folder_list.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vmfolder"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityVMFolderListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vmfolder.ListVMFolder, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := vmfolder.ListRequest{
|
||||
RGID: uint64(d.Get("rg_id").(int)),
|
||||
}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderListCheckPresence: load vm folder list")
|
||||
|
||||
folderList, err := c.CloudAPI().VMFolder().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return folderList, nil
|
||||
}
|
||||
@@ -21,6 +21,7 @@ func flattenGrid(d *schema.ResourceData, grid *grid.RecordGrid) {
|
||||
d.Set("reserved_ram", grid.ReservedRAM)
|
||||
d.Set("sdn_support", grid.SDNSupport)
|
||||
d.Set("zero_access_enabled", grid.ZeroAccessEnabled)
|
||||
d.Set("vm_folders_enabled", grid.VMFoldersEnabled)
|
||||
}
|
||||
|
||||
func flattenGridList(gl *grid.ListGrids) []map[string]interface{} {
|
||||
@@ -41,6 +42,7 @@ func flattenGridList(gl *grid.ListGrids) []map[string]interface{} {
|
||||
"sdn_support": item.SDNSupport,
|
||||
"zero_access_enabled": item.ZeroAccessEnabled,
|
||||
"bro_enabled": item.BROEnabled,
|
||||
"vm_folders_enabled": item.VMFoldersEnabled,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
@@ -62,6 +62,10 @@ func dataSourceGetGridSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"vm_folders_enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +282,10 @@ func dataSourceGridListSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"vm_folders_enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -112,6 +112,7 @@ func flattenCompute(d *schema.ResourceData, computeRec *compute.RecordCompute, p
|
||||
d.Set("hot_resize", computeRec.HotResize)
|
||||
d.Set("network_interface_naming", computeRec.NetworkInterfaceNaming)
|
||||
d.Set("zone_id", computeRec.ZoneID)
|
||||
d.Set("folder_id", computeRec.FolderID)
|
||||
d.Set("os_version", computeRec.OSVersion)
|
||||
d.Set("cpu_pin", computeRec.CPUPin)
|
||||
d.Set("cpu_alignment_profile", computeRec.CPUAlignmentProfile.Name)
|
||||
@@ -436,6 +437,7 @@ func flattenComputeList(computes *compute.ListComputes) []map[string]interface{}
|
||||
"hot_resize": computeItem.HotResize,
|
||||
"network_interface_naming": computeItem.NetworkInterfaceNaming,
|
||||
"zone_id": computeItem.ZoneID,
|
||||
"folder_id": computeItem.FolderID,
|
||||
"weight": computeItem.Weight,
|
||||
}
|
||||
res = append(res, temp)
|
||||
@@ -527,6 +529,7 @@ func flattenDeletedComputeList(computes *compute.ListDeletedComputes) []map[stri
|
||||
"hot_resize": computeItem.HotResize,
|
||||
"network_interface_naming": computeItem.NetworkInterfaceNaming,
|
||||
"zone_id": computeItem.ZoneID,
|
||||
"folder_id": computeItem.FolderID,
|
||||
"weight": computeItem.Weight,
|
||||
}
|
||||
res = append(res, temp)
|
||||
@@ -877,6 +880,7 @@ func flattenDataCompute(d *schema.ResourceData, compFacts *compute.RecordCompute
|
||||
d.Set("hot_resize", compFacts.HotResize)
|
||||
d.Set("network_interface_naming", compFacts.NetworkInterfaceNaming)
|
||||
d.Set("zone_id", compFacts.ZoneID)
|
||||
d.Set("folder_id", compFacts.FolderID)
|
||||
d.Set("loader_meta_iso", flattenLoaderMetaIso(compFacts.LoaderMetaIso))
|
||||
d.Set("os_version", compFacts.OSVersion)
|
||||
d.Set("weight", compFacts.Weight)
|
||||
|
||||
@@ -1233,6 +1233,10 @@ func dataSourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"weight": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
@@ -1330,6 +1334,16 @@ func dataSourceComputeListSchemaMake() map[string]*schema.Schema {
|
||||
Optional: true,
|
||||
Description: "Zone ID",
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Find by VM folder ID",
|
||||
},
|
||||
"include_descendants": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Description: "Include computes from descendant folders",
|
||||
},
|
||||
"ignore_k8s": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
@@ -1837,6 +1851,10 @@ func dataSourceComputeListSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"weight": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
@@ -2396,6 +2414,10 @@ func dataSourceComputeListDeletedSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"weight": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
@@ -4929,6 +4951,10 @@ func resourceComputeSchemaMake() map[string]*schema.Schema {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"vgpus": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
|
||||
@@ -99,6 +99,12 @@ func utilityDataComputeListCheckPresence(ctx context.Context, d *schema.Resource
|
||||
if zoneID, ok := d.GetOk("zone_id"); ok {
|
||||
req.ZoneID = uint64(zoneID.(int))
|
||||
}
|
||||
if folderID, ok := d.GetOk("folder_id"); ok {
|
||||
req.FolderID = uint64(folderID.(int))
|
||||
}
|
||||
if includeDescendants, ok := d.GetOkExists("include_descendants"); ok {
|
||||
req.IncludeDescendants = includeDescendants.(bool)
|
||||
}
|
||||
|
||||
listComputes, err := c.CloudBroker().Compute().List(ctx, req)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
|
||||
)
|
||||
|
||||
func dataSourceVMFolderRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("dataSourceVMFolderRead: called with folder_id %d", d.Get("folder_id").(int))
|
||||
|
||||
w := dc.Warnings{}
|
||||
folder, err := utilityVMFolderCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
flattenVMFolder(d, folder)
|
||||
|
||||
return w.Get()
|
||||
}
|
||||
|
||||
func DataSourceVMFolder() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceVMFolderRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceVMFolderSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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/dc"
|
||||
)
|
||||
|
||||
func dataSourceVMFolderListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
w := dc.Warnings{}
|
||||
folderList, err := utilityVMFolderListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
|
||||
d.Set("items", flattenVMFolderList(folderList))
|
||||
d.Set("entry_count", folderList.EntryCount)
|
||||
|
||||
return w.Get()
|
||||
}
|
||||
|
||||
func DataSourceVMFolderList() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceVMFolderListRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceVMFolderListSchemaMake(),
|
||||
}
|
||||
}
|
||||
55
internal/service/cloudbroker/vmfolder/flattens.go
Normal file
55
internal/service/cloudbroker/vmfolder/flattens.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vmfolder"
|
||||
)
|
||||
|
||||
func flattenVMFolder(d *schema.ResourceData, folder *vmfolder.RecordVMFolder) {
|
||||
log.Debugf("flattenVMFolder: decoded vm folder ID %d", folder.ID)
|
||||
|
||||
d.Set("folder_id", folder.ID)
|
||||
d.Set("rg_id", folder.RGID)
|
||||
d.Set("gid", folder.GID)
|
||||
d.Set("name", folder.Name)
|
||||
d.Set("acl", flattenVMFolderACL(folder.ACL))
|
||||
d.Set("created_time", folder.CreatedTime)
|
||||
d.Set("parent_id", folder.ParentID)
|
||||
d.Set("status", folder.Status)
|
||||
d.Set("compute_ids", folder.ComputeIDs)
|
||||
d.Set("updated_time", folder.UpdatedTime)
|
||||
}
|
||||
|
||||
func flattenVMFolderACL(acl []vmfolder.ACL) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0, len(acl))
|
||||
for _, item := range acl {
|
||||
temp := map[string]interface{}{
|
||||
"explicit": item.Explicit,
|
||||
"right": item.Right,
|
||||
"status": item.Status,
|
||||
"type": item.Type,
|
||||
"user_group_id": item.UserGroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenVMFolderList(folderList *vmfolder.ListVMFolder) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0, len(folderList.Data))
|
||||
for _, item := range folderList.Data {
|
||||
temp := map[string]interface{}{
|
||||
"id": item.ID,
|
||||
"parent_id": item.ParentID,
|
||||
"name": item.Name,
|
||||
"acl": flattenVMFolderACL(item.ACL),
|
||||
"status": item.Status,
|
||||
"vm_count": item.VMCount,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
182
internal/service/cloudbroker/vmfolder/resource_vm_folder.go
Normal file
182
internal/service/cloudbroker/vmfolder/resource_vm_folder.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vmfolder"
|
||||
"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"
|
||||
)
|
||||
|
||||
func resourceVMFolderCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceVMFolderCreate: called with name %s, rg_id %d", d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
warnings := dc.Warnings{}
|
||||
|
||||
req := vmfolder.CreateRequest{
|
||||
RGID: uint64(d.Get("rg_id").(int)),
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
if parentID, ok := d.GetOk("parent_id"); ok {
|
||||
req.ParentID = uint64(parentID.(int))
|
||||
}
|
||||
|
||||
folderID, err := c.CloudBroker().VMFolder().Create(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(folderID, 10))
|
||||
d.Set("folder_id", folderID)
|
||||
|
||||
if aclAccess, ok := d.GetOk("acl_access"); ok {
|
||||
if err := utilityVMFolderACLAccessAdd(ctx, m, folderID, aclAccess.(*schema.Set).List()); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("computes_move"); ok {
|
||||
if err := utilityVMFolderComputesMove(ctx, d, m, folderID); err != nil {
|
||||
warnings.Add(err)
|
||||
}
|
||||
}
|
||||
|
||||
return append(warnings.Get(), resourceVMFolderRead(ctx, d, m)...)
|
||||
}
|
||||
|
||||
func resourceVMFolderRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceVMFolderRead: called with id %s", d.Id())
|
||||
|
||||
w := dc.Warnings{}
|
||||
|
||||
folder, err := utilityVMFolderCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
flattenVMFolder(d, folder)
|
||||
|
||||
return w.Get()
|
||||
}
|
||||
|
||||
func resourceVMFolderUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceVMFolderUpdate: called with id %s", d.Id())
|
||||
|
||||
if d.HasChange("rg_id") {
|
||||
return diag.Errorf("resourceVMFolderUpdate: rg_id can't be changed")
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
folderID, err := strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if d.HasChange("name") {
|
||||
req := vmfolder.RenameRequest{
|
||||
FolderID: folderID,
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
if _, err := c.CloudBroker().VMFolder().Rename(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("parent_id") {
|
||||
req := vmfolder.MoveRequest{
|
||||
FolderID: folderID,
|
||||
NewParentID: uint64(d.Get("parent_id").(int)),
|
||||
}
|
||||
|
||||
if _, err := c.CloudBroker().VMFolder().Move(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("acl_access") {
|
||||
if err := utilityVMFolderACLAccessUpdate(ctx, d, m, folderID); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChanges("computes_move.#", "computes_move.0.compute_ids", "computes_move.0.folder_id") {
|
||||
if err := utilityVMFolderComputesMove(ctx, d, m, folderID); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
return resourceVMFolderRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceVMFolderDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceVMFolderDelete: called with id %s", d.Id())
|
||||
|
||||
folder, err := utilityVMFolderCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
req := vmfolder.DeleteRequest{
|
||||
FolderID: folder.ID,
|
||||
}
|
||||
|
||||
if _, err := c.CloudBroker().VMFolder().Delete(ctx, req); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ResourceVMFolder() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
|
||||
if diff.HasChanges("name", "parent_id", "acl_access", "computes_move.#", "computes_move.0.compute_ids", "computes_move.0.folder_id") {
|
||||
diff.SetNewComputed("updated_time")
|
||||
}
|
||||
if diff.HasChange("acl_access") {
|
||||
diff.SetNewComputed("acl")
|
||||
}
|
||||
if diff.HasChanges("computes_move.#", "computes_move.0.compute_ids", "computes_move.0.folder_id") {
|
||||
diff.SetNewComputed("compute_ids")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
||||
CreateContext: resourceVMFolderCreate,
|
||||
ReadContext: resourceVMFolderRead,
|
||||
UpdateContext: resourceVMFolderUpdate,
|
||||
DeleteContext: resourceVMFolderDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout600s,
|
||||
Read: &constants.Timeout600s,
|
||||
Update: &constants.Timeout600s,
|
||||
Delete: &constants.Timeout600s,
|
||||
Default: &constants.Timeout600s,
|
||||
},
|
||||
|
||||
Schema: resourceVMFolderSchemaMake(),
|
||||
}
|
||||
}
|
||||
266
internal/service/cloudbroker/vmfolder/schema.go
Normal file
266
internal/service/cloudbroker/vmfolder/schema.go
Normal file
@@ -0,0 +1,266 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
)
|
||||
|
||||
func resourceVMFolderSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "ID of the resource group",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the vm folder",
|
||||
},
|
||||
"parent_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the parent vm folder",
|
||||
},
|
||||
"computes_move": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_ids": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of computes to move",
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the target vm folder. If not set, computes are moved to this vm folder",
|
||||
},
|
||||
},
|
||||
},
|
||||
Description: "Move computes to the vm folder",
|
||||
},
|
||||
"acl_access": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"user": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "User or group name to grant access",
|
||||
},
|
||||
"right": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"R", "RCX", "ARCXDU"}, false),
|
||||
Description: "Access rights to set, one of 'R', 'RCX' or 'ARCXDU'",
|
||||
},
|
||||
},
|
||||
},
|
||||
Description: "ACL access rules for the vm folder",
|
||||
},
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the vm folder",
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Grid ID",
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: aclSchemaMake(),
|
||||
},
|
||||
Description: "Access control list of the vm folder",
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Time of creation",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Status of the vm folder",
|
||||
},
|
||||
"compute_ids": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of computes in the vm folder",
|
||||
},
|
||||
"updated_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Time of update",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceVMFolderSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"folder_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "ID of the vm folder",
|
||||
},
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the resource group",
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Grid ID",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the vm folder",
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: aclSchemaMake(),
|
||||
},
|
||||
Description: "Access control list of the vm folder",
|
||||
},
|
||||
"created_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Time of creation",
|
||||
},
|
||||
"parent_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the parent vm folder",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Status of the vm folder",
|
||||
},
|
||||
"compute_ids": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of computes in the vm folder",
|
||||
},
|
||||
"updated_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Time of update",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceVMFolderListSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Find by resource group ID",
|
||||
},
|
||||
"page": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Page number",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Page size",
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the vm folder",
|
||||
},
|
||||
"parent_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the parent vm folder",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the vm folder",
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: aclSchemaMake(),
|
||||
},
|
||||
Description: "Access control list of the vm folder",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Status of the vm folder",
|
||||
},
|
||||
"vm_count": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Number of computes in the vm folder",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"entry_count": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func aclSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"explicit": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Whether the access is explicit",
|
||||
},
|
||||
"right": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Access rights",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Access status",
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Access type",
|
||||
},
|
||||
"user_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "User or group ID",
|
||||
},
|
||||
}
|
||||
}
|
||||
117
internal/service/cloudbroker/vmfolder/utility_vm_folder.go
Normal file
117
internal/service/cloudbroker/vmfolder/utility_vm_folder.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vmfolder"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityVMFolderCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vmfolder.RecordVMFolder, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := vmfolder.GetRequest{}
|
||||
|
||||
if d.Id() != "" {
|
||||
id, err := strconv.ParseUint(d.Id(), 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.FolderID = id
|
||||
} else {
|
||||
req.FolderID = uint64(d.Get("folder_id").(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderCheckPresence: get vm folder with ID %d", req.FolderID)
|
||||
|
||||
folder, err := c.CloudBroker().VMFolder().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return folder, nil
|
||||
}
|
||||
|
||||
func utilityVMFolderComputesMove(ctx context.Context, d *schema.ResourceData, m interface{}, folderID uint64) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
computesMove := d.Get("computes_move").([]interface{})
|
||||
if len(computesMove) == 0 || computesMove[0] == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
item := computesMove[0].(map[string]interface{})
|
||||
|
||||
computeIDs := make([]uint64, 0)
|
||||
for _, id := range item["compute_ids"].(*schema.Set).List() {
|
||||
computeIDs = append(computeIDs, uint64(id.(int)))
|
||||
}
|
||||
if len(computeIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
req := vmfolder.ComputesMoveRequest{
|
||||
ComputeIDs: computeIDs,
|
||||
FolderID: folderID,
|
||||
}
|
||||
if targetFolderID := item["folder_id"].(int); targetFolderID != 0 {
|
||||
req.FolderID = uint64(targetFolderID)
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderComputesMove: move computes %v to vm folder with ID %d", computeIDs, req.FolderID)
|
||||
|
||||
_, err := c.CloudBroker().VMFolder().ComputesMove(ctx, req)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func utilityVMFolderACLAccessAdd(ctx context.Context, m interface{}, folderID uint64, aclAccess []interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
for _, aclInterface := range aclAccess {
|
||||
aclItem := aclInterface.(map[string]interface{})
|
||||
|
||||
req := vmfolder.AddACLAccessRequest{
|
||||
FolderID: folderID,
|
||||
User: aclItem["user"].(string),
|
||||
Right: aclItem["right"].(string),
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderACLAccessAdd: add ACL access %s for user %s to vm folder with ID %d", req.Right, req.User, folderID)
|
||||
|
||||
if _, err := c.CloudBroker().VMFolder().AddACLAccess(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func utilityVMFolderACLAccessUpdate(ctx context.Context, d *schema.ResourceData, m interface{}, folderID uint64) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
|
||||
oldSet, newSet := d.GetChange("acl_access")
|
||||
|
||||
deletedAccess := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List()
|
||||
for _, deletedInterface := range deletedAccess {
|
||||
deletedItem := deletedInterface.(map[string]interface{})
|
||||
|
||||
req := vmfolder.DelACLAccessRequest{
|
||||
FolderID: folderID,
|
||||
User: deletedItem["user"].(string),
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderACLAccessUpdate: delete ACL access for user %s from vm folder with ID %d", req.User, folderID)
|
||||
|
||||
if _, err := c.CloudBroker().VMFolder().DeleteACLAccess(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
addedAccess := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List()
|
||||
|
||||
return utilityVMFolderACLAccessAdd(ctx, m, folderID, addedAccess)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package vmfolder
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vmfolder"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityVMFolderListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vmfolder.ListVMFolder, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := vmfolder.ListRequest{
|
||||
RGID: uint64(d.Get("rg_id").(int)),
|
||||
}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityVMFolderListCheckPresence: load vm folder list")
|
||||
|
||||
folderList, err := c.CloudBroker().VMFolder().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return folderList, nil
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package defaultsecuritypolicy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
func dataSourceDefaultSecurityPolicyListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
defaultSecurityPolicyList, err := utilityDefaultSecurityPolicyListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("items", flattenDefaultSecurityPolicyList(defaultSecurityPolicyList))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func DataSourceDefaultSecurityPolicyList() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceDefaultSecurityPolicyListRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceDefaultSecurityPolicyListSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
package defaultsecuritypolicy
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/defsecpolicies"
|
||||
)
|
||||
|
||||
func flattenDefaultSecurityPolicyList(policyList *defsecpolicies.SecurityPoliciesList) []map[string]interface{} {
|
||||
if policyList == nil {
|
||||
return []map[string]interface{}{}
|
||||
}
|
||||
res := make([]map[string]interface{}, 0, len(policyList.Policies))
|
||||
for _, v := range policyList.Policies {
|
||||
temp := map[string]interface{}{
|
||||
"access_group_id": v.AccessGroupID,
|
||||
"created_at": v.CreatedAt,
|
||||
"default_acl_drop": v.DefaultACLDrop,
|
||||
"default_open_session_drop": v.DefaultOpenSessionDrop,
|
||||
"description": v.Description,
|
||||
"display_name": v.DisplayName,
|
||||
"id": v.ID,
|
||||
"security_rules": flattenSecurityRules(v.SecurityRules),
|
||||
"locked_at": v.LockedAt,
|
||||
"status": flattenStatus(v.Status),
|
||||
"version_id": int(v.VersionID),
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenSecurityRules(rules []defsecpolicies.SecurityRule) []map[string]interface{} {
|
||||
if rules == nil {
|
||||
return []map[string]interface{}{}
|
||||
}
|
||||
res := make([]map[string]interface{}, 0, len(rules))
|
||||
for _, v := range rules {
|
||||
temp := map[string]interface{}{
|
||||
"access_group_id": v.AccessGroupID,
|
||||
"action": v.Action,
|
||||
"description": v.Description,
|
||||
"destination_net_object": flattenNetObject(v.DestinationNetObject),
|
||||
"direction": v.Direction,
|
||||
"display_name": v.DisplayName,
|
||||
"enabled": v.Enabled,
|
||||
"filter": flattenFilter(v.Filter),
|
||||
"id": v.ID,
|
||||
"log_enabled": v.LogEnabled,
|
||||
"log_name": v.LogName,
|
||||
"log_severity": v.LogSeverity,
|
||||
"priority": v.Priority,
|
||||
"security_policy_id": v.SecurityPolicyID,
|
||||
"source_net_object": flattenNetObject(v.SourceNetObject),
|
||||
"statistics_enabled": v.StatisticsEnabled,
|
||||
"version_id": int(v.VersionID),
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenNetObject(netObj defsecpolicies.NetObject) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"display_name": netObj.DisplayName,
|
||||
"net_address_pool_id": netObj.NetAddressPoolID,
|
||||
"net_object_group_id": netObj.NetObjectGroupID,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenFilter(filter defsecpolicies.Filter) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"filters": flattenFilterParams(filter.Filters),
|
||||
"name": filter.Name,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenFilterParams(params defsecpolicies.FilterParams) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"all": params.All,
|
||||
"arp": params.ARP,
|
||||
"dhcp": params.DHCP,
|
||||
"expression": params.Expression,
|
||||
"icmp": params.ICMP,
|
||||
"ip": params.IP,
|
||||
"ip_v4": params.IPv4,
|
||||
"ip_v6": params.IPv6,
|
||||
"keep_opened_sessions": params.KeepOpenedSessions,
|
||||
"nd": params.ND,
|
||||
"tcp": params.TCP,
|
||||
"tcp_dst_ports": params.TCPDstPorts,
|
||||
"udp": params.UDP,
|
||||
"udp_dst_ports": params.UDPDstPorts,
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenStatus(status defsecpolicies.Status) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
temp := map[string]interface{}{
|
||||
"common": status.Common,
|
||||
"hypervisors": flattenHypervisorStatuses(status.Hypervisors),
|
||||
}
|
||||
res = append(res, temp)
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenHypervisorStatuses(hypervisors []defsecpolicies.HypervisorStatus) []map[string]interface{} {
|
||||
if hypervisors == nil {
|
||||
return []map[string]interface{}{}
|
||||
}
|
||||
res := make([]map[string]interface{}, 0, len(hypervisors))
|
||||
for _, v := range hypervisors {
|
||||
temp := map[string]interface{}{
|
||||
"status": v.Status,
|
||||
"name": v.Name,
|
||||
"display_name": v.DisplayName,
|
||||
"hypervisor_status": v.HypervisorStatus,
|
||||
"synced_at": v.SyncedAt,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -1,369 +0,0 @@
|
||||
package defaultsecuritypolicy
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
)
|
||||
|
||||
func dataSourceDefaultSecurityPolicyListSchemaMake() map[string]*schema.Schema {
|
||||
res := map[string]*schema.Schema{
|
||||
"access_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "id of the access group",
|
||||
},
|
||||
"page": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "result page number",
|
||||
},
|
||||
"per_page": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "number of results per page",
|
||||
},
|
||||
"sort_by": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"created_at", "updated_at"}, false),
|
||||
Description: "sort by one of the supported fields",
|
||||
},
|
||||
"sort_order": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"asc", "desc"}, false),
|
||||
Description: "sorting order",
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "List of default security policies",
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"access_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Access group ID",
|
||||
},
|
||||
"created_at": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Creation timestamp",
|
||||
},
|
||||
"default_acl_drop": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Default ACL drop action",
|
||||
},
|
||||
"default_open_session_drop": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Default open session drop flag",
|
||||
},
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Description",
|
||||
},
|
||||
"display_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Display name",
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Unique identifier",
|
||||
},
|
||||
"security_rules": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "Security rules",
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"access_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Access group ID",
|
||||
},
|
||||
"action": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Action",
|
||||
},
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Description",
|
||||
},
|
||||
"destination_net_object": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "Destination network object",
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"display_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Display name",
|
||||
},
|
||||
"net_address_pool_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Network address pool ID",
|
||||
},
|
||||
"net_object_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Network object group ID",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"direction": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Direction",
|
||||
},
|
||||
"display_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Display name",
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Enabled flag",
|
||||
},
|
||||
"filter": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "Filter configuration",
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"filters": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "Filter parameters",
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"all": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "All protocols flag",
|
||||
},
|
||||
"arp": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "ARP protocol flag",
|
||||
},
|
||||
"dhcp": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "DHCP protocol flag",
|
||||
},
|
||||
"expression": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Filter expression",
|
||||
},
|
||||
"icmp": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "ICMP protocol flag",
|
||||
},
|
||||
"ip": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "IP protocol flag",
|
||||
},
|
||||
"ip_v4": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "IPv4 protocol flag",
|
||||
},
|
||||
"ip_v6": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "IPv6 protocol flag",
|
||||
},
|
||||
"keep_opened_sessions": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Keep opened sessions flag",
|
||||
},
|
||||
"nd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "ND protocol flag",
|
||||
},
|
||||
"tcp": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "TCP protocol flag",
|
||||
},
|
||||
"tcp_dst_ports": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "TCP destination ports",
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"udp": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "UDP protocol flag",
|
||||
},
|
||||
"udp_dst_ports": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "UDP destination ports",
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Filter name",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Unique identifier",
|
||||
},
|
||||
"log_enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Log enabled flag",
|
||||
},
|
||||
"log_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Log name",
|
||||
},
|
||||
"log_severity": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Log severity",
|
||||
},
|
||||
"priority": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Priority",
|
||||
},
|
||||
"security_policy_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Security policy ID",
|
||||
},
|
||||
"source_net_object": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "Source network object",
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"display_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Display name",
|
||||
},
|
||||
"net_address_pool_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Network address pool ID",
|
||||
},
|
||||
"net_object_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Network object group ID",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"statistics_enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Statistics enabled flag",
|
||||
},
|
||||
"version_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Version ID",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"locked_at": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Locked timestamp",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "Status information",
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"common": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Common status",
|
||||
},
|
||||
"hypervisors": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "Hypervisor statuses",
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Status",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name",
|
||||
},
|
||||
"display_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Display name",
|
||||
},
|
||||
"hypervisor_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Hypervisor status",
|
||||
},
|
||||
"synced_at": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Last sync timestamp",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"version_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Version ID",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package defaultsecuritypolicy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/defsecpolicies"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityDefaultSecurityPolicyListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*defsecpolicies.SecurityPoliciesList, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := defsecpolicies.ListRequest{}
|
||||
|
||||
if accessGroupID, ok := d.GetOk("access_group_id"); ok {
|
||||
req.AccessGroupID = accessGroupID.(string)
|
||||
}
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if perPage, ok := d.GetOk("per_page"); ok {
|
||||
req.PerPage = uint64(perPage.(int))
|
||||
}
|
||||
if sortBy, ok := d.GetOk("sort_by"); ok {
|
||||
req.SortBy = sortBy.(string)
|
||||
}
|
||||
if sortOrder, ok := d.GetOk("sort_order"); ok {
|
||||
req.SortOrder = sortOrder.(string)
|
||||
}
|
||||
|
||||
log.Debugf("utilityDefaultSecurityPolicyListCheckPresence")
|
||||
defaultSecurityPolicyList, err := c.SDN().DefaultSecurityPolicies().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return defaultSecurityPolicyList, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user