Skip to content

Commit 1e1ffed

Browse files
authored
add blockDevices and ISCSI changes for volume resource (#15405)
1 parent 6699a9b commit 1e1ffed

File tree

4 files changed

+225
-4
lines changed

4 files changed

+225
-4
lines changed

mmv1/products/netapp/Volume.yaml

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ update_mask: true
3535
import_format:
3636
- 'projects/{{project}}/locations/{{location}}/volumes/{{name}}'
3737
timeouts:
38-
insert_minutes: 20
39-
update_minutes: 20
40-
delete_minutes: 20
38+
insert_minutes: 50
39+
update_minutes: 30
40+
delete_minutes: 30
4141
autogen_async: true
4242
async:
4343
actions: ['create', 'delete', 'update']
@@ -48,6 +48,8 @@ async:
4848
resource_inside_response: false
4949
custom_code:
5050
pre_delete: 'templates/terraform/pre_delete/netapp_volume_force_delete.go.tmpl'
51+
pre_update: 'templates/terraform/pre_update/netapp_volume_custom_block_devices_update.tmpl'
52+
constants: 'templates/terraform/constants/netapp_volume.go.tmpl'
5153
examples:
5254
- name: 'netapp_volume_basic'
5355
primary_resource_id: 'test_volume'
@@ -103,7 +105,6 @@ properties:
103105
type: String
104106
description: |
105107
Share name (SMB) or export path (NFS) of the volume. Needs to be unique per location.
106-
required: true
107108
immutable: true
108109
- name: 'psaRange'
109110
type: String
@@ -219,6 +220,7 @@ properties:
219220
- 'NFSV3'
220221
- 'NFSV4'
221222
- 'SMB'
223+
- 'ISCSI'
222224
- name: 'smbSettings'
223225
type: Array
224226
description: |
@@ -618,3 +620,58 @@ properties:
618620
description: |
619621
Total hot tier data rounded down to the nearest GiB used by the volume. This field is only used for flex Service Level
620622
output: true
623+
- name: 'blockDevices'
624+
type: Array
625+
description: |
626+
Block device represents the device(s) which are stored in the block volume.
627+
Currently, only one block device is permitted per Volume.
628+
item_type:
629+
type: NestedObject
630+
properties:
631+
- name: 'name'
632+
type: String
633+
description: |
634+
User-defined name for the block device, unique within the Volume. In case
635+
no user input is provided, name will be autogenerated in the backend.
636+
The name must meet the following requirements:
637+
* Be between 1 and 255 characters long.
638+
* Contain only uppercase or lowercase letters (A-Z, a-z), numbers (0-9),
639+
and the following special characters: "-", "_", "}", "{", ".".
640+
* Spaces are not allowed.
641+
default_from_api: true
642+
- name: 'hostGroups'
643+
type: Array
644+
description: |
645+
A list of host groups that identify hosts that can mount the block volume.
646+
Format:
647+
`projects/{project_id}/locations/{location}/hostGroups/{host_group_id}`
648+
This field can be updated after the block device is created.
649+
default_from_api: true
650+
diff_suppress_func: 'ProjectIDDiffSuppress'
651+
item_type:
652+
type: String
653+
- name: 'identifier'
654+
type: String
655+
description: |
656+
Device identifier of the Block volume. This represents lun_serial_number
657+
for ISCSI volumes
658+
output: true
659+
- name: 'sizeGib'
660+
type: Integer
661+
description: |
662+
The size of the block device in GiB.
663+
Any value provided in this field during Volume creation is IGNORED.
664+
The block device's size is system-managed and will be set to match
665+
the parent Volume's `capacity_gib`.
666+
output: true
667+
- name: 'osType'
668+
type: Enum
669+
description: |
670+
The OS type of the volume.
671+
This field can't be changed after the block device is created.
672+
immutable: true
673+
required: true
674+
enum_values:
675+
- 'LINUX'
676+
- 'WINDOWS'
677+
- 'ESXI'
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Suppress diffs when the value read from api
2+
// has the project ID instead of the project number
3+
func ProjectIDDiffSuppress(_, old, new string, _ *schema.ResourceData) bool {
4+
5+
const marker = "/locations"
6+
7+
// Find the starting index of "/locations" in both strings.
8+
index1 := strings.Index(old, marker)
9+
index2 := strings.Index(new, marker)
10+
11+
// If "/locations" is not found in either string, they can't be compared as requested.
12+
if index1 == -1 || index2 == -1 {
13+
return false
14+
}
15+
16+
// Extract the substrings from the marker to the end.
17+
suffix1 := old[index1:]
18+
suffix2 := new[index2:]
19+
20+
// Compare the extracted suffixes.
21+
return suffix1 == suffix2
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// remove sizeGib and identifier from the update request for block_devices
2+
3+
if v, ok := d.GetOk("block_devices"); ok {
4+
5+
l := v.([]interface{})
6+
newBlockDevices := make([]interface{}, 0, len(l))
7+
8+
for _, item := range v.([]interface{}) {
9+
if item == nil { continue }
10+
blockDevice := item.(map[string]interface{})
11+
newblockDevice := make(map[string]interface{})
12+
13+
if val, exists := blockDevice["name"]; exists { newblockDevice["name"] = val }
14+
if val, exists := blockDevice["host_groups"]; exists { newblockDevice["host_groups"] = val }
15+
if val, exists := blockDevice["os_type"]; exists { newblockDevice["os_type"] = val }
16+
17+
newBlockDevices = append(newBlockDevices, newblockDevice)
18+
}
19+
20+
log.Printf("newBlockDevices %v", newBlockDevices)
21+
if len(newBlockDevices) > 0 {
22+
obj["blockDevices"] = newBlockDevices
23+
}
24+
}

mmv1/third_party/terraform/services/netapp/resource_netapp_volume_test.go.tmpl

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,3 +1311,121 @@ func testAccNetappVolume_volumeExportPolicyWithoutSquashModeUpdate(context map[s
13111311
`, context)
13121312
}
13131313
{{ end }}
1314+
1315+
func TestAccNetappBlockVolume_NetappVolumeBasicExample_update(t *testing.T) {
1316+
context := map[string]interface{}{
1317+
"network_name": acctest.BootstrapSharedServiceNetworkingConnection(t, "gcnv-network-config-3", acctest.ServiceNetworkWithParentService("netapp.servicenetworking.goog")),
1318+
"random_suffix": acctest.RandString(t, 10),
1319+
}
1320+
1321+
acctest.VcrTest(t, resource.TestCase{
1322+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1323+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1324+
CheckDestroy: testAccCheckNetappVolumeDestroyProducer(t),
1325+
ExternalProviders: map[string]resource.ExternalProvider{
1326+
"time": {},
1327+
},
1328+
Steps: []resource.TestStep{
1329+
{
1330+
Config: testAccNetappBlockVolume_volumeBasicExample_basic(context),
1331+
},
1332+
{
1333+
ResourceName: "google_netapp_volume.test_volume",
1334+
ImportState: true,
1335+
ImportStateVerify: true,
1336+
ImportStateVerifyIgnore: []string{"restore_parameters", "location", "name", "deletion_policy", "labels", "terraform_labels"},
1337+
},
1338+
{
1339+
Config: testAccNetappBlockVolume_volumeBasicExample_update(context),
1340+
},
1341+
{
1342+
ResourceName: "google_netapp_volume.test_volume",
1343+
ImportState: true,
1344+
ImportStateVerify: true,
1345+
ImportStateVerifyIgnore: []string{"restore_parameters", "location", "name", "deletion_policy", "labels", "terraform_labels"},
1346+
},
1347+
},
1348+
})
1349+
}
1350+
1351+
func testAccNetappBlockVolume_volumeBasicExample_basic(context map[string]interface{}) string {
1352+
return acctest.Nprintf(`
1353+
resource "google_netapp_storage_pool" "default" {
1354+
name = "tf-test-test-pool%{random_suffix}"
1355+
location = "us-central1-a"
1356+
service_level = "FLEX"
1357+
capacity_gib = "2048"
1358+
type = "UNIFIED"
1359+
network = data.google_compute_network.default.id
1360+
}
1361+
1362+
resource "google_netapp_host_group" "test_host_group" {
1363+
name = "tf-test-test-host-group%{random_suffix}"
1364+
location = "us-central1"
1365+
os_type = "LINUX"
1366+
type = "ISCSI_INITIATOR"
1367+
hosts = ["iqn.1994-05.com.redhat:8518f79d5366"]
1368+
}
1369+
1370+
resource "google_netapp_volume" "test_volume" {
1371+
location = "us-central1-a"
1372+
name = "tf_test_test_volume%{random_suffix}"
1373+
capacity_gib = "100"
1374+
storage_pool = google_netapp_storage_pool.default.name
1375+
protocols = ["ISCSI"]
1376+
block_devices {
1377+
host_groups = [google_netapp_host_group.test_host_group.id]
1378+
os_type = "LINUX"
1379+
}
1380+
}
1381+
1382+
data "google_compute_network" "default" {
1383+
name = "%{network_name}"
1384+
}
1385+
`, context)
1386+
}
1387+
1388+
func testAccNetappBlockVolume_volumeBasicExample_update(context map[string]interface{}) string {
1389+
return acctest.Nprintf(`
1390+
resource "google_netapp_storage_pool" "default" {
1391+
name = "tf-test-test-pool%{random_suffix}"
1392+
location = "us-central1-a"
1393+
service_level = "FLEX"
1394+
capacity_gib = "2048"
1395+
type = "UNIFIED"
1396+
network = data.google_compute_network.default.id
1397+
}
1398+
1399+
resource "google_netapp_host_group" "test_host_group" {
1400+
name = "tf-test-test-host-group%{random_suffix}"
1401+
location = "us-central1"
1402+
os_type = "LINUX"
1403+
type = "ISCSI_INITIATOR"
1404+
hosts = ["iqn.1994-05.com.redhat:8518f79d5366"]
1405+
}
1406+
1407+
resource "google_netapp_host_group" "test_host_group2" {
1408+
name = "tf-test-test-host2-group%{random_suffix}"
1409+
location = "us-central1"
1410+
os_type = "LINUX"
1411+
type = "ISCSI_INITIATOR"
1412+
hosts = ["iqn.1994-05.com.debian:8518f79d5366"]
1413+
}
1414+
1415+
resource "google_netapp_volume" "test_volume" {
1416+
location = "us-central1-a"
1417+
name = "tf_test_test_volume%{random_suffix}"
1418+
capacity_gib = "100"
1419+
storage_pool = google_netapp_storage_pool.default.name
1420+
protocols = ["ISCSI"]
1421+
block_devices {
1422+
host_groups = [google_netapp_host_group.test_host_group.id, google_netapp_host_group.test_host_group2.id]
1423+
os_type = "LINUX"
1424+
}
1425+
}
1426+
1427+
data "google_compute_network" "default" {
1428+
name = "%{network_name}"
1429+
}
1430+
`, context)
1431+
}

0 commit comments

Comments
 (0)