Skip to content

Commit

Permalink
add new attributes [attachmentType, protocol, disks] to Volume Group
Browse files Browse the repository at this point in the history
  • Loading branch information
Haroon-Dweikat-Ntx committed Dec 12, 2024
1 parent e9bd475 commit 176e502
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 20 deletions.
19 changes: 19 additions & 0 deletions nutanix/services/volumesv2/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package volumesv2_test

import (
"fmt"
acc "github.com/terraform-providers/terraform-provider-nutanix/nutanix/acctest"
"log"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
Expand Down Expand Up @@ -40,6 +42,23 @@ func testAccCheckResourceAttrListNotEmpty(resourceName, attrName, subAttr string
}
}

func testAccCheckNutanixVolumeGroupV2Destroy(s *terraform.State) error {
conn := acc.TestAccProvider.Meta().(*conns.Client)

for _, rs := range s.RootModule().Resources {
if rs.Type != "nutanix_volume_group_v2" {
continue
}
if _, err := conn.VolumeAPI.VolumeAPIInstance.DeleteVolumeGroupById(utils.StringPtr(rs.Primary.ID)); err != nil {
if strings.Contains(fmt.Sprint(err), "VOLUME_UNKNOWN_ENTITY_ERROR") {
return nil
}
return err
}
}
return nil
}

func resourceNutanixVolumeGroupV2Exists(conn *conns.Client, name string) (*string, error) {
var vgUUID *string

Expand Down
179 changes: 162 additions & 17 deletions nutanix/services/volumesv2/resource_nutanix_volume_group_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,89 @@ func ResourceNutanixVolumeGroupV2() *schema.Resource {
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"USER", "INTERNAL", "TEMPORARY", "BACKUP_TARGET"}, false),
},
"attachment_type": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"EXTERNAL", "NONE", "DIRECT"}, false),
},
"protocol": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"NOT_ASSIGNED", "ISCSI", "NVMF"}, false),
},
"is_hidden": {
Description: "Indicates whether the Volume Group is meant to be hidden or not. This is an optional field. If omitted, the VG will not be hidden.",
Type: schema.TypeBool,
Optional: true,
Default: false,
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"disks": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"index": {
Type: schema.TypeInt,
Optional: true,
},
"disk_size_bytes": {
Type: schema.TypeInt,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"disk_data_source_reference": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ext_id": {
Type: schema.TypeString,
Required: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
},
"uris": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"entity_type": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"STORAGE_CONTAINER", "VM_DISK", "VOLUME_DISK", "DISK_RECOVERY_POINT"}, false),
},
},
},
},
"disk_storage_features": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"flash_mode": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"is_enabled": {
Type: schema.TypeBool,
Optional: true,
},
},
},
},
},
},
},
},
},
},
},
}
Expand Down Expand Up @@ -173,18 +251,19 @@ func ResourceNutanixVolumeGroupV2Create(ctx context.Context, d *schema.ResourceD
if targetName, ok := d.GetOk("target_name"); ok {
body.TargetName = utils.StringPtr(targetName.(string))
}
// if enabledAuthentications, ok := d.GetOk("enabled_authentications"); ok {
// enabledAuthenticationsMap := map[string]interface{}{
// "CHAP": 2,
// "NONE": 3,
// }
// pVal := enabledAuthenticationsMap[enabledAuthentications.(string)]
// p := volumesClient.AuthenticationType(pVal.(int))
// body.EnabledAuthentications = &p
// } else {
// p := volumesClient.AuthenticationType(0) // Replace 0 with the appropriate default value
// body.EnabledAuthentications = &p
// }
if enabledAuthentications, ok := d.GetOk("enabled_authentications"); ok {
enabledAuthenticationsMap := map[string]interface{}{
"CHAP": 2,

Check failure on line 256 in nutanix/services/volumesv2/resource_nutanix_volume_group_v2.go

View workflow job for this annotation

GitHub Actions / tests

mnd: Magic number: 2, in <assign> detected (gomnd)

Check failure on line 256 in nutanix/services/volumesv2/resource_nutanix_volume_group_v2.go

View workflow job for this annotation

GitHub Actions / tests

mnd: Magic number: 2, in <assign> detected (gomnd)
"NONE": 3,

Check failure on line 257 in nutanix/services/volumesv2/resource_nutanix_volume_group_v2.go

View workflow job for this annotation

GitHub Actions / tests

mnd: Magic number: 3, in <assign> detected (gomnd)

Check failure on line 257 in nutanix/services/volumesv2/resource_nutanix_volume_group_v2.go

View workflow job for this annotation

GitHub Actions / tests

mnd: Magic number: 3, in <assign> detected (gomnd)
}
pVal := enabledAuthenticationsMap[enabledAuthentications.(string)]
if pVal == nil {
body.EnabledAuthentications = nil
} else {
p := volumesClient.AuthenticationType(pVal.(int))
body.EnabledAuthentications = &p
}
}
if iscsiFeatures, ok := d.GetOk("iscsi_features"); ok {
body.IscsiFeatures = expandIscsiFeatures(iscsiFeatures.([]interface{}))
}
Expand All @@ -210,10 +289,42 @@ func ResourceNutanixVolumeGroupV2Create(ctx context.Context, d *schema.ResourceD
p := volumesClient.UsageType(pInt.(int))
body.UsageType = &p
}
if attachmentType, ok := d.GetOk("attachment_type"); ok {
const NONE, DIRECT, EXTERNAL = 2, 3, 4
attachmentTypeMap := map[string]interface{}{
"NONE": NONE,
"DIRECT": DIRECT,
"EXTERNAL": EXTERNAL,
}
pInt := attachmentTypeMap[attachmentType.(string)]
if pInt == nil {
body.AttachmentType = nil
} else {
p := volumesClient.AttachmentType(pInt.(int))
body.AttachmentType = &p
}
}
if protocol, ok := d.GetOk("protocol"); ok {
const NotAssigned, ISCSI, NVMF = 2, 3, 4
protocolMap := map[string]interface{}{
"NotAssigned": NotAssigned,
"ISCSI": ISCSI,
"NVMF": NVMF,
}
pInt := protocolMap[protocol.(string)]
if pInt == nil {
body.Protocol = nil
} else {
p := volumesClient.Protocol(pInt.(int))
body.Protocol = &p
}
}
if isHidden, ok := d.GetOk("is_hidden"); ok {
body.IsHidden = utils.BoolPtr(isHidden.(bool))
}

if disks, ok := d.GetOk("disks"); ok {
body.Disks = expandDisks(disks.([]interface{}))
}
resp, err := conn.VolumeAPIInstance.CreateVolumeGroup(&body)
if err != nil {
return diag.Errorf("error while creating Volume Group : %v", err)
Expand Down Expand Up @@ -408,6 +519,40 @@ func expandFlashMode(flashModeList []interface{}) *volumesClient.FlashMode {
return nil
}

func expandDisks(disks []interface{}) []volumesClient.VolumeDisk {

if len(disks) == 0 {
return nil
}

disksList := make([]volumesClient.VolumeDisk, len(disks))

for k, v := range disks {
disk := volumesClient.VolumeDisk{}

diskI := v.(map[string]interface{})

if index, ok := diskI["index"]; ok {
disk.Index = utils.IntPtr(index.(int))
}
if diskSizeBytes, ok := diskI["disk_size_bytes"]; ok {
diskSize := int64(diskSizeBytes.(int))
disk.DiskSizeBytes = utils.Int64Ptr(diskSize)
}
if description, ok := diskI["description"]; ok {
disk.Description = utils.StringPtr(description.(string))
}
if diskDataSourceReference, ok := diskI["disk_data_source_reference"]; ok {
disk.DiskDataSourceReference = expandDiskDataSourceReference(diskDataSourceReference.([]interface{}))
}
if diskStorageFeatures, ok := diskI["disk_storage_features"]; ok {
disk.DiskStorageFeatures = expandDiskStorageFeatures(diskStorageFeatures.([]interface{}))
}
disksList[k] = disk
}
return disksList
}

func taskStateRefreshPrismTaskGroupFunc(ctx context.Context, client *prism.Client, taskUUID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
vresp, err := client.TaskRefAPI.GetTaskById(utils.StringPtr(taskUUID), nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ func TestAccV2NutanixVolumeGroupResource_Basic(t *testing.T) {
desc := "test volume group description"

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
// CheckDestroy: testAccCheckNutanixVolumeGroupV4Destroy,
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckNutanixVolumeGroupV2Destroy,
Steps: []resource.TestStep{
{
Config: testAccVolumeGroupResourceConfig(name, desc),
Expand Down Expand Up @@ -87,6 +87,39 @@ func TestAccV2NutanixVolumeGroupResource_WithNoClusterReference(t *testing.T) {
})
}

func TestAccV2NutanixVolumeGroupResource_WithAttachmentTypeAndProtocolAndDisks(t *testing.T) {
r := acctest.RandInt()
name := fmt.Sprintf("tf-test-volume-group-%d", r)
desc := "test volume group description with attachment type and protocol and disks"

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckNutanixVolumeGroupV2Destroy,
Steps: []resource.TestStep{
{
Config: testAccVolumeGroupResourceConfigWithAttachmentTypeAndProtocolAndDisks(name, desc),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "name", name),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "description", desc),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "should_load_balance_vm_attachments", "false"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "sharing_status", "SHARED"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "created_by", "admin"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "iscsi_features.0.enabled_authentications", "CHAP"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "storage_features.0.flash_mode.0.is_enabled", "true"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "is_hidden", "false"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "usage_type", "USER"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "attachment_type", "DIRECT"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "protocol", "ISCSI"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "disks.0.disk_size_bytes", "10737418240"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "disks.0.index", "1"),
resource.TestCheckResourceAttr(resourceNameVolumeGroup, "disks.0.disk_storage_features.0.flash_mode.0.is_enabled", "false"),
),
},
},
})
}

// VG just required attributes
func testAccVolumeGroupV2RequiredAttributes(name string) string {
return fmt.Sprintf(`
Expand Down Expand Up @@ -131,3 +164,63 @@ func testAccVolumeGroupV2ConfigWithNoClusterReference(name string) string {
}
`, name)
}

func testAccVolumeGroupResourceConfigWithAttachmentTypeAndProtocolAndDisks(name string, desc string) string {
return fmt.Sprintf(`
data "nutanix_clusters_v2" "clusters" {}
locals {
cluster1 = [
for cluster in data.nutanix_clusters_v2.clusters.cluster_entities :
cluster.ext_id if cluster.config[0].cluster_function[0] != "PRISM_CENTRAL"
][0]
}
data "nutanix_storage_containers_v2" "test" {
filter = "clusterExtId eq '${local.cluster1}'"
limit = 1
}
resource "nutanix_volume_group_v2" "test" {
name = "%[1]s"
description = "%[2]s"
should_load_balance_vm_attachments = false
sharing_status = "SHARED"
created_by = "admin"
cluster_reference = local.cluster1
iscsi_features {
target_secret = "1234567891011"
enabled_authentications = "CHAP"
}
storage_features {
flash_mode {
is_enabled = true
}
}
usage_type = "USER"
attachment_type = "DIRECT"
protocol = "ISCSI"
disks {
disk_size_bytes = 10 * 1024 * 1024 * 1024
index = 1
disk_data_source_reference {
name = "vg-disk-%[1]s"
ext_id = data.nutanix_storage_containers_v2.test.storage_containers[0].ext_id
entity_type = "STORAGE_CONTAINER"
uris = ["uri1","uri2"]
}
disk_storage_features {
flash_mode {
is_enabled = false
}
}
}
is_hidden = false
lifecycle {
ignore_changes = [
iscsi_features[0].target_secret
]
}
}
`, name, desc)
}

0 comments on commit 176e502

Please sign in to comment.