-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Resource to prepare for NSXT cluster upgrade
Signed-off-by: Shizhao Liu <[email protected]>
- Loading branch information
Shizhao Liu
committed
Jan 3, 2024
1 parent
b8b33d1
commit 9221914
Showing
5 changed files
with
394 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* Copyright © 2023 VMware, Inc. All Rights Reserved. | ||
SPDX-License-Identifier: MPL-2.0 */ | ||
|
||
package nsxt | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
nsxModel "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/model" | ||
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/upgrade" | ||
) | ||
|
||
func resourceNsxtUpgradePrecheckAcknowledge() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceNsxtUpgradePrecheckAcknowledgeCreate, | ||
Read: resourceNsxtUpgradePrecheckAcknowledgeRead, | ||
Update: resourceNsxtUpgradePrecheckAcknowledgeUpdate, | ||
Delete: resourceNsxtUpgradePrecheckAcknowledgeDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"precheck_id": { | ||
Type: schema.TypeList, | ||
Description: "IDs of failed prechecks that user wants to acknowledge before upgrade", | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"id": { | ||
Type: schema.TypeString, | ||
Description: "ID of failed precheck to acknowledge", | ||
Required: true, | ||
}, | ||
}, | ||
}, | ||
Required: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceNsxtUpgradePrecheckAcknowledgeCreate(d *schema.ResourceData, m interface{}) error { | ||
id := d.Id() | ||
if id == "" { | ||
id = newUUID() | ||
} | ||
d.SetId(id) | ||
precheckIDs := interface2StringList(d.Get("precheck_id").([]interface{})) | ||
connector := getPolicyConnector(m) | ||
client := upgrade.NewPreUpgradeChecksClient(connector) | ||
for _, precheckID := range precheckIDs { | ||
err := client.Acknowledge(precheckID) | ||
if err != nil { | ||
return handleCreateError("NsxtUpgradePrecheckAcknowledge", id, err) | ||
} | ||
} | ||
return resourceNsxtUpgradePrecheckAcknowledgeRead(d, m) | ||
} | ||
|
||
func resourceNsxtUpgradePrecheckAcknowledgeRead(d *schema.ResourceData, m interface{}) error { | ||
id := d.Id() | ||
precheckWarnings, err := getPrecheckErrors(m, nsxModel.UpgradeCheckFailure_TYPE_WARNING) | ||
if err != nil { | ||
return handleReadError(d, "NsxtUpgradePrecheckAcknowledge", id, err) | ||
} | ||
err = setAcknowledgedPrecheckIDsInSchema(d, precheckWarnings) | ||
if err != nil { | ||
return handleReadError(d, "NsxtUpgradePrecheckAcknowledge", id, err) | ||
} | ||
return nil | ||
} | ||
|
||
func setAcknowledgedPrecheckIDsInSchema(d *schema.ResourceData, precheckWarnings []nsxModel.UpgradeCheckFailure) error { | ||
var precheckWarningIDs []map[string]interface{} | ||
for _, precheckWarning := range precheckWarnings { | ||
elem := make(map[string]interface{}) | ||
if !(*precheckWarning.NeedsAck) { | ||
id := *precheckWarning.Id | ||
elem["id"] = id | ||
precheckWarningIDs = append(precheckWarningIDs, elem) | ||
} | ||
} | ||
return d.Set("precheck_id", precheckWarningIDs) | ||
} | ||
|
||
func resourceNsxtUpgradePrecheckAcknowledgeUpdate(d *schema.ResourceData, m interface{}) error { | ||
return nil | ||
} | ||
|
||
func resourceNsxtUpgradePrecheckAcknowledgeDelete(d *schema.ResourceData, m interface{}) error { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
/* Copyright © 2023 VMware, Inc. All Rights Reserved. | ||
SPDX-License-Identifier: MPL-2.0 */ | ||
|
||
package nsxt | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx" | ||
nsxModel "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/model" | ||
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/upgrade" | ||
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/upgrade/bundles" | ||
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/upgrade/eula" | ||
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/upgrade/pre_upgrade_checks" | ||
) | ||
|
||
func resourceNsxtUpgradePrepare() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceNsxtUpgradePrepareCreate, | ||
Read: resourceNsxtUpgradePrepareRead, | ||
Update: resourceNsxtUpgradePrepareUpdate, | ||
Delete: resourceNsxtUpgradePrepareDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"bundle_url": { | ||
Type: schema.TypeString, | ||
Description: "URL of the NSXT Upgrade bundle", | ||
Required: true, | ||
}, | ||
"version": { | ||
Type: schema.TypeString, | ||
Description: "Version for the upgrade", | ||
Required: true, | ||
}, | ||
"accept_user_agreement": { | ||
Type: schema.TypeBool, | ||
Description: "Whether to accept the user agreement", | ||
Required: true, | ||
}, | ||
"failed_prechecks": { | ||
Type: schema.TypeList, | ||
Description: "List of failed prechecks for the upgrade, only include warnings, if precheck failed with error then the resource creation will fail", | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"id": { | ||
Type: schema.TypeString, | ||
Description: "ID of failed precheck", | ||
Computed: true, | ||
}, | ||
"message": { | ||
Type: schema.TypeString, | ||
Description: "Message of the failed precheck", | ||
Computed: true, | ||
}, | ||
// "needs_ack": { | ||
// Type: schema.TypeBool, | ||
// Description: "Flag which identifies if acknowledgement is required for the precheck", | ||
// Computed: true, | ||
// }, | ||
// "needs_resolve": { | ||
// Type: schema.TypeBool, | ||
// Description: "Flag which identifies if resolution is required for the precheck", | ||
// ValidateFunc: validation.IsIPAddress, | ||
// Required: true, | ||
// }, | ||
}, | ||
}, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func uploadUpgradeBundle(d *schema.ResourceData, m interface{}) error { | ||
connector := getPolicyConnector(m) | ||
bundleURL := d.Get("bundle_url").(string) | ||
version := d.Get("version").(string) | ||
client := upgrade.NewBundlesClient(connector) | ||
installParam := false | ||
bundleType := nsxModel.UpgradeBundleFetchRequest_BUNDLE_TYPE_PRE_UPGRADE | ||
c := m.(nsxtClients) | ||
userName := c.NsxtClientConfig.UserName | ||
password := c.NsxtClientConfig.Password | ||
upgradeBundleFetchRequest := nsxModel.UpgradeBundleFetchRequest{ | ||
BundleType: &bundleType, | ||
Password: &password, | ||
Username: &userName, | ||
Url: &bundleURL, | ||
Version: &version, | ||
} | ||
bundleID, err := client.Create(upgradeBundleFetchRequest, &installParam) | ||
if err != nil { | ||
return handleCreateError("NsxtUpgradePrepare", "", err) | ||
} | ||
err = waitForBundleUpload(m, *bundleID.BundleId) | ||
if err != nil { | ||
return handleCreateError("NsxtUpgradePrepare", "", err) | ||
} | ||
return nil | ||
} | ||
|
||
func acceptUserAgreement(d *schema.ResourceData, m interface{}) error { | ||
connector := getPolicyConnector(m) | ||
acceptUserAgreement := d.Get("accept_user_agreement").(bool) | ||
if !acceptUserAgreement { | ||
return fmt.Errorf("To proceed with upgrade, you must accept user agreement") | ||
} | ||
client := eula.NewAcceptClient(connector) | ||
err := client.Create() | ||
if err != nil { | ||
return handleCreateError("NsxtUpgradePrepare", "", err) | ||
} | ||
return nil | ||
} | ||
|
||
func executePreupgradeChecks(m interface{}) error { | ||
connector := getPolicyConnector(m) | ||
client := nsx.NewUpgradeClient(connector) | ||
return client.Executepreupgradechecks(nil, nil, nil, nil, nil, nil) | ||
} | ||
|
||
func getPrecheckErrors(m interface{}, typeParam string) ([]nsxModel.UpgradeCheckFailure, error) { | ||
connector := getPolicyConnector(m) | ||
client := pre_upgrade_checks.NewFailuresClient(connector) | ||
resultList, err := client.List(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, &typeParam, nil, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return resultList.Results, nil | ||
} | ||
|
||
func setFailedPrechecksInSchema(d *schema.ResourceData, precheckWarnings []nsxModel.UpgradeCheckFailure) error { | ||
var failedPrechecksList []map[string]interface{} | ||
for _, warning := range precheckWarnings { | ||
id := *warning.Id | ||
message := *(warning.Message.Message) | ||
elem := make(map[string]interface{}) | ||
elem["id"] = id | ||
elem["message"] = message | ||
failedPrechecksList = append(failedPrechecksList, elem) | ||
} | ||
return d.Set("failed_prechecks", failedPrechecksList) | ||
} | ||
|
||
func resourceNsxtUpgradePrepareCreate(d *schema.ResourceData, m interface{}) error { | ||
id := d.Id() | ||
if id == "" { | ||
id = newUUID() | ||
} | ||
d.SetId(id) | ||
// 1. Upload upgrade bundle and wait for upload to complete, | ||
// UC will be automatically upgraded after this step | ||
err := uploadUpgradeBundle(d, m) | ||
if err != nil { | ||
return handleCreateError("NsxtUpgradePrepare", id, err) | ||
} | ||
// 2. Accept user agreement | ||
err = acceptUserAgreement(d, m) | ||
if err != nil { | ||
return handleCreateError("NsxtUpgradePrepare", id, err) | ||
} | ||
// 3. Execute pre-upgrade checks | ||
err = executePreupgradeChecks(m) | ||
if err != nil { | ||
return handleCreateError("NsxtUpgradePrepare", id, err) | ||
} | ||
// 4. Check if there is error in prechecks | ||
precheckFailures, err := getPrecheckErrors(m, nsxModel.UpgradeCheckFailure_TYPE_FAILURE) | ||
if err != nil { | ||
return handleCreateError("NsxtUpgradePrepare", id, err) | ||
} | ||
if len(precheckFailures) > 0 { | ||
return handleCreateError("NsxtUpgradePrepare", id, fmt.Errorf("Encounter errors in precheck %s", *(precheckFailures[0].Message.Message))) | ||
} | ||
return resourceNsxtUpgradePrepareRead(d, m) | ||
} | ||
|
||
func resourceNsxtUpgradePrepareRead(d *schema.ResourceData, m interface{}) error { | ||
id := d.Id() | ||
precheckWarnings, err := getPrecheckErrors(m, nsxModel.UpgradeCheckFailure_TYPE_WARNING) | ||
if err != nil { | ||
return handleReadError(d, "NsxtUpgradePrepare", id, err) | ||
} | ||
err = setFailedPrechecksInSchema(d, precheckWarnings) | ||
if err != nil { | ||
return handleReadError(d, "NsxtUpgradePrepare", id, err) | ||
} | ||
return nil | ||
} | ||
|
||
func resourceNsxtUpgradePrepareUpdate(d *schema.ResourceData, m interface{}) error { | ||
return nil | ||
} | ||
|
||
func resourceNsxtUpgradePrepareDelete(d *schema.ResourceData, m interface{}) error { | ||
return nil | ||
} | ||
|
||
func waitForBundleUpload(m interface{}, bundleID string) error { | ||
connector := getPolicyConnector(m) | ||
client := bundles.NewUploadStatusClient(connector) | ||
// c := m.(nsxtClients) | ||
// Todo: | ||
// 1. utilize Min/Max RetryInterval in provider config | ||
interval := 20000 | ||
maxRetry := 50 | ||
for i := 0; i < 50; i++ { | ||
uploadStatus, err := client.Get(bundleID) | ||
if err != nil { | ||
return err | ||
} | ||
if *uploadStatus.Status == nsxModel.UpgradeBundleUploadStatus_STATUS_FAILED { | ||
return fmt.Errorf("Failed to upload upgrade bundle with id %s", bundleID) | ||
} | ||
if *uploadStatus.Status == nsxModel.UpgradeBundleUploadStatus_STATUS_SUCCESS { | ||
log.Printf("[DEBUG]: successfully uploaded upgrade bundle %s", bundleID) | ||
return nil | ||
} | ||
// interval := (rand.Intn(max-min) + min) | ||
time.Sleep(time.Duration(interval) * time.Millisecond) | ||
log.Printf("[DEBUG]: Waited %d ms before retrying getting upgrade bundle upload status", interval) | ||
} | ||
return fmt.Errorf("Upload bundle %s exceed timeout %v seconds", bundleID, (interval*maxRetry)/1000) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
--- | ||
subcategory: "Beta" | ||
layout: "nsxt" | ||
page_title: "NSXT: nsxt_upgrade_precheck_acknowledge" | ||
description: A resource to acknowledge failed NSXT upgrade prechecks. | ||
--- | ||
|
||
# nsxt_upgrade_precheck_acknowledge | ||
|
||
This resource provides a method for acknowledging the failed prechecks | ||
for NSXT upgrade. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
resource "nsxt_upgrade_precheck_acknowledge" "test" { | ||
precheck_id { | ||
id = "backupOperationCheck" | ||
} | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `precheck_id` - (Required) List of ids of failed prechecks user want to acknowledge. | ||
* `id` - (Required) Id of failed prechecks. | ||
|
||
## Importing | ||
|
||
Importing is not supported for this resource. |
Oops, something went wrong.