Skip to content

Commit 90104bb

Browse files
committed
Version check for NVMe host
Updating and deleting the NVMe host in PowerFlex versions earlier than 4.6 is not supported
1 parent d823c06 commit 90104bb

File tree

11 files changed

+129
-26
lines changed

11 files changed

+129
-26
lines changed

docs/resources/nvme_host.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ description: |-
2626

2727
This resource is used to manager NVMe host from the PowerFlex array. We can Create, Update and Delete the PowerFlex NVMe host using this resource. We can also import an existing NVMe host from PowerFlex array.
2828

29+
Please note that due to certain limitations, updating the NVMe host in PowerFlex versions earlier than 4.6 is not supported
30+
2931
## Example Usage
3032

3133
```terraform
@@ -51,6 +53,7 @@ limitations under the License.
5153
# To import , check import.sh for more info
5254
# nqn is the required parameter to create
5355
# To check which attributes can be updated, please refer Product Guide in the documentation
56+
# Please note that due to certain limitations, updating the NVMe host in PowerFlex versions earlier than 4.6 is not supported
5457
5558
# Example for adding NVMe host.
5659
resource "powerflex_nvme_host" "test-nvme-host" {

examples/resources/powerflex_nvme_host/resource.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ limitations under the License.
2020
# To import , check import.sh for more info
2121
# nqn is the required parameter to create
2222
# To check which attributes can be updated, please refer Product Guide in the documentation
23+
# Please note that due to certain limitations, updating the NVMe host in PowerFlex versions earlier than 4.6 is not supported
2324

2425
# Example for adding NVMe host.
2526
resource "powerflex_nvme_host" "test-nvme-host" {

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ toolchain go1.23.2
77
require (
88
github.com/bramvdbogaerde/go-scp v1.5.0
99
github.com/bytedance/mockey v1.2.13
10-
github.com/dell/goscaleio v1.17.1-0.20241106124128-c895c8717b22
10+
github.com/dell/goscaleio v1.17.1-0.20241112041929-3499a2af3b98
1111
github.com/hashicorp/terraform-plugin-framework v1.11.0
1212
github.com/hashicorp/terraform-plugin-framework-validators v0.13.0
1313
github.com/hashicorp/terraform-plugin-go v0.23.0
@@ -95,7 +95,7 @@ require (
9595
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
9696
github.com/zclconf/go-cty v1.15.0 // indirect
9797
golang.org/x/net v0.25.0 // indirect
98-
golang.org/x/sys v0.26.0 // indirect
98+
golang.org/x/sys v0.27.0 // indirect
9999
golang.org/x/text v0.17.0 // indirect
100100
google.golang.org/appengine v1.6.8 // indirect
101101
google.golang.org/grpc v1.63.2 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
3333
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3434
github.com/dell/goscaleio v1.17.1-0.20241106124128-c895c8717b22 h1:Ox4ra5FUj1LWL3M1ibMxPCzWLue2yRzYdhSuRsLYEDc=
3535
github.com/dell/goscaleio v1.17.1-0.20241106124128-c895c8717b22/go.mod h1:dB1a2wXevGps25VAda+6WDp+NTUdgMZXvQVM0YOBpX8=
36+
github.com/dell/goscaleio v1.17.1-0.20241112041929-3499a2af3b98 h1:MBv+SdBrNADVJIT1XBFgKVWP6BddGOVRpu11iDJQ+oA=
37+
github.com/dell/goscaleio v1.17.1-0.20241112041929-3499a2af3b98/go.mod h1:OGFdDzRGhiAkXDTyrOUM42mxco5Y/vnhUyw/G7uXDzs=
3638
github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURUI=
3739
github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ=
3840
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
@@ -280,6 +282,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
280282
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
281283
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
282284
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
285+
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
286+
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
283287
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
284288
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
285289
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=

powerflex/provider/POWERFLEX_TERRAFORM_TEST.env.sample

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ POWERFLEX_PROTECTION_DOMAIN_ID_SDS=
3131
POWERFLEX_STORAGE_POOL_NAME=
3232
POWERFLEX_SERVICE_ID=
3333
POWERFLEX_SERVICE_NAME=
34+
POWERFLEX_NVME_HOST_NAME=
35+
POWERFLEX_NVME_HOST_NAME_CREATE=
36+
POWERFLEX_NVME_HOST_NAME_UPDATE=
37+
POWERFLEX_NVME_HOST_NQN=
3438
POWERFLEX_NVME_TARGET_NAME=
3539
POWERFLEX_NVME_TARGET_NAME_CREATE=
3640
POWERFLEX_NVME_TARGET_NAME_UPDATE=

powerflex/provider/nvme_host_datasource_test.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ import (
3030

3131
var nvmeHostDatasourceConfig = `
3232
data "powerflex_nvme_host" "nvme_host_datasource" {
33-
filter {
34-
name = ["nvme_acc_client1001"]
35-
}
33+
3634
}
3735
`
38-
var nvmeHostDatasourceNoFilterConfig = `
36+
37+
var nvmeHostDatasourceConfigFilter = `
3938
data "powerflex_nvme_host" "nvme_host_datasource" {
40-
39+
filter {
40+
name = ["` + NVMeHostName + `"]
41+
}
4142
}
4243
`
4344

@@ -55,9 +56,9 @@ func TestAccDatasourceNvmeHost(t *testing.T) {
5556
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
5657
Steps: []resource.TestStep{
5758
{
58-
Config: ProviderConfigForTesting + nvmeHostDatasourceNoFilterConfig,
59+
Config: ProviderConfigForTesting + nvmeHostDatasourceConfig,
5960
Check: resource.ComposeAggregateTestCheckFunc(
60-
resource.TestCheckResourceAttr("data.powerflex_nvme_host.nvme_host_datasource", "nvme_host_details.#", "1"),
61+
listCountGreaterThan("data.powerflex_nvme_host.nvme_host_datasource", "nvme_host_details", 0),
6162
),
6263
},
6364
{
@@ -69,7 +70,7 @@ func TestAccDatasourceNvmeHost(t *testing.T) {
6970
{ID: "mock-id", HostType: "NVMeHost", SystemID: "mock-system-id", Name: "", Nqn: "mock-nqn", MaxNumPaths: 4, MaxNumSysPorts: 10},
7071
}, nil).Build()
7172
},
72-
Config: ProviderConfigForTesting + nvmeHostDatasourceNoFilterConfig,
73+
Config: ProviderConfigForTesting + nvmeHostDatasourceConfig,
7374
Check: resource.ComposeAggregateTestCheckFunc(
7475
resource.TestCheckResourceAttr("data.powerflex_nvme_host.nvme_host_datasource", "nvme_host_details.#", "1"),
7576
resource.TestCheckResourceAttr("data.powerflex_nvme_host.nvme_host_datasource", "nvme_host_details.0.name", "NVMeHost:mock-id"),
@@ -92,11 +93,9 @@ func TestAccDatasourceNvmeHost(t *testing.T) {
9293
FunctionMocker.UnPatch()
9394
}
9495
},
95-
Config: ProviderConfigForTesting + nvmeHostDatasourceConfig,
96+
Config: ProviderConfigForTesting + nvmeHostDatasourceConfigFilter,
9697
Check: resource.ComposeAggregateTestCheckFunc(
97-
resource.TestCheckResourceAttr("data.powerflex_nvme_host.nvme_host_datasource", "nvme_host_details.0.name", "nvme_acc_client1001"),
98-
resource.TestCheckResourceAttr("data.powerflex_nvme_host.nvme_host_datasource", "nvme_host_details.0.max_num_paths", "4"),
99-
resource.TestCheckResourceAttr("data.powerflex_nvme_host.nvme_host_datasource", "nvme_host_details.0.max_num_sys_ports", "10"),
98+
resource.TestCheckResourceAttr("data.powerflex_nvme_host.nvme_host_datasource", "nvme_host_details.0.name", NVMeHostName),
10099
),
101100
},
102101
},
@@ -115,7 +114,7 @@ func TestAccDatasourceNvmeHostNegative(t *testing.T) {
115114
}
116115
FunctionMocker = Mock(helper.GetFirstSystem).Return(nil, fmt.Errorf("mock error")).Build()
117116
},
118-
Config: ProviderConfigForTesting + nvmeHostDatasourceConfig,
117+
Config: ProviderConfigForTesting + nvmeHostDatasourceConfigFilter,
119118
ExpectError: regexp.MustCompile(`.*Unable to Read Powerflex specific system*.`),
120119
},
121120
{
@@ -125,7 +124,7 @@ func TestAccDatasourceNvmeHostNegative(t *testing.T) {
125124
}
126125
FunctionMocker = Mock((*goscaleio.System).GetAllNvmeHosts).Return(nil, fmt.Errorf("mock error")).Build()
127126
},
128-
Config: ProviderConfigForTesting + nvmeHostDatasourceConfig,
127+
Config: ProviderConfigForTesting + nvmeHostDatasourceConfigFilter,
129128
ExpectError: regexp.MustCompile(`.*Unable to Read Powerflex NVMe Hosts*.`),
130129
},
131130
},

powerflex/provider/nvme_host_resource.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,23 @@ func (r *NvmeHostResource) Update(ctx context.Context, req resource.UpdateReques
224224
return
225225
}
226226

227+
result, err := goscaleio.CheckPfmpVersion(r.client, "4.6")
228+
229+
if err != nil {
230+
resp.Diagnostics.AddError(
231+
"Error checking PowerFlex version",
232+
err.Error(),
233+
)
234+
return
235+
}
236+
if result < 0 {
237+
resp.Diagnostics.AddError(
238+
"Updating NVMe host is not supported",
239+
"Updating the NVMe host is not supported in PowerFlex versions earlier than 4.6",
240+
)
241+
return
242+
}
243+
227244
if !plan.Nqn.Equal(state.Nqn) {
228245
resp.Diagnostics.AddError(
229246
"nqn cannot be modified after creation",

powerflex/provider/nvme_host_resource_test.go

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@ import (
3232

3333
var nvmeHostResourceConfig = `
3434
resource "powerflex_nvme_host" "nvme_host_test" {
35-
name = "nvme_acc_client1002"
36-
nqn = "nqn.2014-08.org.nvmexpress:uuid:a10e4d56-a2c0-4cab-9a0a-9a7a4ebb8c0e"
35+
name = "` + NVMeHostNameCreate + `"
36+
nqn = "` + NVMeHostNqn + `"
3737
max_num_paths = 4
3838
max_num_sys_ports = 10
3939
}
4040
`
4141

4242
var nvmeHostResourceConfigUpdate = `
4343
resource "powerflex_nvme_host" "nvme_host_test" {
44-
name = "nvme_acc_client1002_update"
45-
nqn = "nqn.2014-08.org.nvmexpress:uuid:a10e4d56-a2c0-4cab-9a0a-9a7a4ebb8c0e"
44+
name = "` + NVMeHostNameUpdate + `"
45+
nqn = "` + NVMeHostNqn + `"
4646
max_num_paths = 8
4747
max_num_sys_ports = 8
4848
}
@@ -57,8 +57,8 @@ func TestAccNvmeHostResource(t *testing.T) {
5757
{
5858
Config: ProviderConfigForTesting + nvmeHostResourceConfig,
5959
Check: resource.ComposeAggregateTestCheckFunc(
60-
resource.TestCheckResourceAttr(resourceName, "name", "nvme_acc_client1002"),
61-
resource.TestCheckResourceAttr(resourceName, "nqn", "nqn.2014-08.org.nvmexpress:uuid:a10e4d56-a2c0-4cab-9a0a-9a7a4ebb8c0e"),
60+
resource.TestCheckResourceAttr(resourceName, "name", NVMeHostNameCreate),
61+
resource.TestCheckResourceAttr(resourceName, "nqn", NVMeHostNqn),
6262
resource.TestCheckResourceAttr(resourceName, "max_num_paths", "4"),
6363
resource.TestCheckResourceAttr(resourceName, "max_num_sys_ports", "10"),
6464
),
@@ -73,7 +73,7 @@ func TestAccNvmeHostResource(t *testing.T) {
7373
{
7474
Config: ProviderConfigForTesting + nvmeHostResourceConfigUpdate,
7575
Check: resource.ComposeAggregateTestCheckFunc(
76-
resource.TestCheckResourceAttr(resourceName, "name", "nvme_acc_client1002_update"),
76+
resource.TestCheckResourceAttr(resourceName, "name", NVMeHostNameUpdate),
7777
resource.TestCheckResourceAttr(resourceName, "max_num_paths", "8"),
7878
resource.TestCheckResourceAttr(resourceName, "max_num_sys_ports", "8"),
7979
),
@@ -82,7 +82,7 @@ func TestAccNvmeHostResource(t *testing.T) {
8282
{
8383
Config: ProviderConfigForTesting + nvmeHostResourceConfig,
8484
Check: resource.ComposeAggregateTestCheckFunc(
85-
resource.TestCheckResourceAttr(resourceName, "name", "nvme_acc_client1002"),
85+
resource.TestCheckResourceAttr(resourceName, "name", NVMeHostNameCreate),
8686
resource.TestCheckResourceAttr(resourceName, "max_num_paths", "4"),
8787
resource.TestCheckResourceAttr(resourceName, "max_num_sys_ports", "10"),
8888
),
@@ -166,7 +166,7 @@ func TestAccNvmeHostResourceNegative(t *testing.T) {
166166
{
167167
Config: ProviderConfigForTesting + nvmeHostResourceConfig,
168168
Check: resource.ComposeAggregateTestCheckFunc(
169-
resource.TestCheckResourceAttr(resourceName, "name", "nvme_acc_client1002"),
169+
resource.TestCheckResourceAttr(resourceName, "name", NVMeHostNameCreate),
170170
resource.TestCheckResourceAttr(resourceName, "max_num_paths", "4"),
171171
resource.TestCheckResourceAttr(resourceName, "max_num_sys_ports", "10"),
172172
),
@@ -191,6 +191,16 @@ func TestAccNvmeHostResourceHelperNegative(t *testing.T) {
191191
resource.Test(t, resource.TestCase{
192192
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
193193
Steps: []resource.TestStep{
194+
{
195+
PreConfig: func() {
196+
if FunctionMocker != nil {
197+
FunctionMocker.UnPatch()
198+
}
199+
FunctionMocker = Mock(helper.GetFirstSystem).Return(nil, fmt.Errorf("mock error")).Build()
200+
},
201+
Config: ProviderConfigForTesting + nvmeHostResourceConfig,
202+
ExpectError: regexp.MustCompile(`.*Error in getting system instance on the PowerFlex cluster.*`),
203+
},
194204
{
195205
PreConfig: func() {
196206
if FunctionMocker != nil {
@@ -242,6 +252,61 @@ func TestAccNvmeHostResourceHelperNegative(t *testing.T) {
242252
Config: ProviderConfigForTesting + nvmeHostResourceConfigUpdate,
243253
ExpectError: regexp.MustCompile(`.*Could not read NVMe host struct.*`),
244254
},
255+
// mock checking PowerFlex version when udpating
256+
{
257+
PreConfig: func() {
258+
if FunctionMocker != nil {
259+
FunctionMocker.UnPatch()
260+
}
261+
FunctionMocker = Mock(goscaleio.CheckPfmpVersion).Return(-1, fmt.Errorf("mock error")).Build()
262+
},
263+
Config: ProviderConfigForTesting + nvmeHostResourceConfigUpdate,
264+
ExpectError: regexp.MustCompile(`.*Error checking PowerFlex version*.`),
265+
},
266+
// updating is not allowed prior to 4.6
267+
{
268+
PreConfig: func() {
269+
if FunctionMocker != nil {
270+
FunctionMocker.UnPatch()
271+
}
272+
FunctionMocker = Mock(goscaleio.CheckPfmpVersion).Return(-1, nil).Build()
273+
},
274+
Config: ProviderConfigForTesting + nvmeHostResourceConfigUpdate,
275+
ExpectError: regexp.MustCompile(`.*Updating NVMe host is not supported*.`),
276+
},
277+
// mock checking PowerFlex version when deleting
278+
{
279+
PreConfig: func() {
280+
if FunctionMocker != nil {
281+
FunctionMocker.UnPatch()
282+
}
283+
FunctionMocker = Mock(goscaleio.CheckPfmpVersion).Return(-1, fmt.Errorf("mock error")).Build()
284+
},
285+
Config: ProviderConfigForTesting,
286+
ExpectError: regexp.MustCompile(`.*Error checking PowerFlex version*.`),
287+
},
288+
// deleting is not allowed prior to 4.6
289+
{
290+
PreConfig: func() {
291+
if FunctionMocker != nil {
292+
FunctionMocker.UnPatch()
293+
}
294+
FunctionMocker = Mock(goscaleio.CheckPfmpVersion).Return(-1, nil).Build()
295+
},
296+
Config: ProviderConfigForTesting,
297+
ExpectError: regexp.MustCompile(`.*Deleting NVMe host is not supported*.`),
298+
},
299+
// error deleting
300+
{
301+
PreConfig: func() {
302+
if FunctionMocker != nil {
303+
FunctionMocker.UnPatch()
304+
}
305+
FunctionMocker = Mock((*goscaleio.System).DeleteNvmeHost).Return(fmt.Errorf("mock error")).Build()
306+
},
307+
Config: ProviderConfigForTesting,
308+
ExpectError: regexp.MustCompile(`.*Unable to delete NVMe host*.`),
309+
},
245310
// rollback nvme host
246311
{
247312
PreConfig: func() {
@@ -251,7 +316,7 @@ func TestAccNvmeHostResourceHelperNegative(t *testing.T) {
251316
},
252317
Config: ProviderConfigForTesting + nvmeHostResourceConfig,
253318
Check: resource.ComposeAggregateTestCheckFunc(
254-
resource.TestCheckResourceAttr(resourceName, "name", "nvme_acc_client1002"),
319+
resource.TestCheckResourceAttr(resourceName, "name", NVMeHostNameCreate),
255320
resource.TestCheckResourceAttr(resourceName, "max_num_paths", "4"),
256321
resource.TestCheckResourceAttr(resourceName, "max_num_sys_ports", "10"),
257322
),

powerflex/provider/powerflex.env

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ POWERFLEX_RCG_ID=
7979
POWERFLEX_SOURCE_PROTECTION_DOMAIN_ID=
8080
POWERFLEX_REMOTE_PROTECTION_DOMAIN_ID=
8181
POWERFLEX_DESTINATION_SYSTEM_ID=
82+
POWERFLEX_NVME_HOST_NAME=
83+
POWERFLEX_NVME_HOST_NAME_CREATE=
84+
POWERFLEX_NVME_HOST_NAME_UPDATE=
85+
POWERFLEX_NVME_HOST_NQN=
8286
POWERFLEX_NVME_TARGET_NAME=
8387
POWERFLEX_NVME_TARGET_NAME_CREATE=
8488
POWERFLEX_NVME_TARGET_NAME_UPDATE=

powerflex/provider/provider_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,10 @@ var PeerMdmName = setDefault(globalEnvMap["POWERFLEX_PEER_MDM_NAME"], "tfacc_pee
357357
var PeerMdmID = setDefault(globalEnvMap["POWERFLEX_PEER_MDM_ID"], "tfacc_peer_mdm_id")
358358
var PeerMdmPort = setDefault(globalEnvMap["POWERFLEX_PEER_MDM_PORT"], "2222")
359359
var PeerMdmCouplingRC = setDefault(globalEnvMap["POWERFLEX_PEER_MDM_COUPLING_RC"], "tfacc_peer_mdm_coupling_rc")
360+
var NVMeHostName = setDefault(globalEnvMap["POWERFLEX_NVME_HOST_NAME"], "nvme_acc_client1001")
361+
var NVMeHostNameCreate = setDefault(globalEnvMap["POWERFLEX_NVME_HOST_NAME_CREATE"], "nvme_acc_client1002")
362+
var NVMeHostNameUpdate = setDefault(globalEnvMap["POWERFLEX_NVME_HOST_NAME_UPDATE"], "nvme_acc_client1002_update")
363+
var NVMeHostNqn = setDefault(globalEnvMap["POWERFLEX_NVME_HOST_NQN"], "nqn.2014-08.org.nvmexpress:uuid:a10e4d56-a2c0-4cab-9a0a-9a7a4ebb8c0e")
360364
var NVMeTargetName = setDefault(globalEnvMap["POWERFLEX_NVME_TARGET_NAME"], "mock-name-1")
361365
var NVMeTargetNameCreate = setDefault(globalEnvMap["POWERFLEX_NVME_TARGET_NAME_CREATE"], "tfacc_nvme_target_name")
362366
var NVMeTargetNameUpdate = setDefault(globalEnvMap["POWERFLEX_NVME_TARGET_NAME_UPDATE"], "tfacc_nvme_target_name_update")

templates/resources/nvme_host.md.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ description: |-
2626

2727
{{ .Description | trimspace }}
2828

29+
Please note that due to certain limitations, updating the NVMe host in PowerFlex versions earlier than 4.6 is not supported
30+
2931
{{ if .HasExample -}}
3032
## Example Usage
3133

0 commit comments

Comments
 (0)