4.13.1
This commit is contained in:
2026-10-30 16:23:20 +03:00
parent 2b229a84fb
commit cd3310836b
63 changed files with 2375 additions and 1029 deletions

View File

@@ -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,

View File

@@ -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,

View File

@@ -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))

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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,
},
},
},
},

View 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(),
}
}

View 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(),
}
}

View 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
}

View 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(),
}
}

View 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)
}

View 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
}

View File

@@ -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)
}

View File

@@ -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,
},
},
},
},

View File

@@ -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)

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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(),
}
}

View File

@@ -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(),
}
}

View 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
}

View 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(),
}
}

View 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",
},
}
}

View 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)
}

View 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/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
}

View File

@@ -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(),
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}