Skip to content

Commit

Permalink
Stop IP and ESXi block from updating in sdc_host res (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
rounak-adhikary committed Jun 14, 2024
1 parent 6716757 commit d9b00e9
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 1 deletion.
35 changes: 35 additions & 0 deletions powerflex/helper/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
Licensed under the Mozilla Public License Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://mozilla.org/MPL/2.0/
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package helper

import (
"github.com/hashicorp/terraform-plugin-framework/attr"
)

func isKnown(v attr.Value) bool {
return !(v.IsUnknown() || v.IsNull())
}

// Known returns true if all values are known
func Known(vs ...attr.Value) bool {
for _, v := range vs {
if !isKnown(v) {
return false
}
}
return true
}
3 changes: 2 additions & 1 deletion powerflex/helper/sdc_host_esxi.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,10 @@ func (r *SdcHostResource) CreateEsxi(ctx context.Context, plan models.SdcHostMod
tflog.Info(ctx, "Checking for installed scini module")
op, err = esxi.GetModuleByName("scini")
if err != nil {
tflog.Info(ctx, "Scini module not found: "+op)
respDiagnostics.AddError(
"Scini module not found after reboot 2",
err.Error()+"\n"+op,
err.Error()+"\nPlease verify that the input GUID and MDM IPs are correct.",
)
return respDiagnostics
}
Expand Down
46 changes: 46 additions & 0 deletions powerflex/provider/sdc_host_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,52 @@ func (r *sdcHostResource) Configure(_ context.Context, req resource.ConfigureReq
r.system = system
}

// ModifyPlan handles plan modification
func (r *sdcHostResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
// If the entire plan is null, the resource is planned for destruction. Dont do anything.
if req.Plan.Raw.IsNull() {
return
}

// Retrieve values from plan
var plan models.SdcHostModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

// if resource is getting created
if req.State.Raw.IsNull() {
return
}
// Only update scenarios from here on

// Retrieve values from state
var state models.SdcHostModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

// if esxi block is getting updated, throw error
if helper.Known(state.Esxi, plan.Esxi) && !state.Esxi.Equal(plan.Esxi) {
resp.Diagnostics.AddAttributeError(
path.Root("esxi"),
"ESXi SDC details cannot be updated",
"",
)
}

// if IP is getting updated, throw error
if helper.Known(state.Host, plan.Host) && !state.Host.Equal(plan.Host) {
resp.Diagnostics.AddAttributeError(
path.Root("ip"),
"SDC IP cannot be updated through this resource",
"Please update the SDC IP by other means and refresh state by running terraform apply -refresh-only",
)
}
}

// Create creates the resource and sets the initial Terraform state.
func (r *sdcHostResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
// Retrieve values from plan
Expand Down
90 changes: 90 additions & 0 deletions powerflex/provider/sdc_host_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,26 @@ func TestAccSDCHostResourceUbuntu(t *testing.T) {
SdcHostResourceTestData.UbuntuPkgPath, strings.Join(SdcHostResourceTestData.MdmIPs, `", "`)),
ExpectError: regexp.MustCompile(`.*mdm_ips cannot be changed.*`),
},
// Update ip negative
{
Config: ProviderConfigForTesting + fmt.Sprintf(`
resource powerflex_sdc_host sdc {
ip = "10.10.10.10"
remote = {
port = "%s"
user = "%s"
password = "%s"
}
os_family = "linux"
name = "sdc-ubuntu2"
package_path = "%s"
mdm_ips = ["%s"]
}
`, SdcHostResourceTestData.UbuntuPort, SdcHostResourceTestData.UbuntuUser, SdcHostResourceTestData.UbuntuPassword,
SdcHostResourceTestData.UbuntuPkgPath, strings.Join(SdcHostResourceTestData.MdmIPs, `", "`)),
PlanOnly: true,
ExpectError: regexp.MustCompile(`.*SDC IP cannot be updated through this resource.*`),
},
// Update package negative
{
Config: ProviderConfigForTesting + fmt.Sprintf(`
Expand Down Expand Up @@ -522,6 +542,76 @@ func TestAccSDCHostResourceEsxi(t *testing.T) {
strings.Join(SdcHostResourceTestData.MdmIPs, `", "`)),
ExpectError: regexp.MustCompile(`.*package cannot be changed.*`),
},
// Update guid negative
{
Config: ProviderConfigForTesting + randomGUID + fmt.Sprintf(`
resource powerflex_sdc_host sdc {
ip = "%s"
remote = {
port = "%s"
user = "%s"
password = "%s"
}
esxi = {
guid = "invalid"
}
os_family = "esxi"
name = "sdc-esxi2"
package_path = "/dummy/tfaccsdc2.tar"
mdm_ips = ["%s"]
}
`, SdcHostResourceTestData.EsxiIP, SdcHostResourceTestData.EsxiPort, SdcHostResourceTestData.EsxiUser, SdcHostResourceTestData.EsxiPassword,
strings.Join(SdcHostResourceTestData.MdmIPs, `", "`)),
PlanOnly: true,
ExpectError: regexp.MustCompile(`.*ESXi SDC details cannot be updated.*`),
},
// Update vib ignore negative
{
Config: ProviderConfigForTesting + randomGUID + fmt.Sprintf(`
resource powerflex_sdc_host sdc {
ip = "%s"
remote = {
port = "%s"
user = "%s"
password = "%s"
}
esxi = {
guid = random_uuid.sdc_guid.result
verify_vib_signature = false
}
os_family = "esxi"
name = "sdc-esxi2"
package_path = "/dummy/tfaccsdc2.tar"
mdm_ips = ["%s"]
}
`, SdcHostResourceTestData.EsxiIP, SdcHostResourceTestData.EsxiPort, SdcHostResourceTestData.EsxiUser, SdcHostResourceTestData.EsxiPassword,
strings.Join(SdcHostResourceTestData.MdmIPs, `", "`)),
PlanOnly: true,
ExpectError: regexp.MustCompile(`.*ESXi SDC details cannot be updated.*`),
},
// Update IP negative
{
Config: ProviderConfigForTesting + randomGUID + fmt.Sprintf(`
resource powerflex_sdc_host sdc {
ip = "10.10.10.10"
remote = {
port = "%s"
user = "%s"
password = "%s"
}
esxi = {
guid = random_uuid.sdc_guid.result
}
os_family = "esxi"
name = "sdc-esxi2"
package_path = "/dummy/tfaccsdc2.tar"
mdm_ips = ["%s"]
}
`, SdcHostResourceTestData.EsxiPort, SdcHostResourceTestData.EsxiUser, SdcHostResourceTestData.EsxiPassword,
strings.Join(SdcHostResourceTestData.MdmIPs, `", "`)),
PlanOnly: true,
ExpectError: regexp.MustCompile(`.*SDC IP cannot be updated through this resource.*`),
},
// Update os negative
{
Config: ProviderConfigForTesting + randomGUID + fmt.Sprintf(`
Expand Down

0 comments on commit d9b00e9

Please sign in to comment.