Skip to content

Commit

Permalink
Merge branch 'master' into hostSwitch_IDvsPath
Browse files Browse the repository at this point in the history
  • Loading branch information
ksamoray authored Sep 21, 2023
2 parents a193131 + 656167a commit b4b1d20
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 85 deletions.
85 changes: 85 additions & 0 deletions nsxt/data_source_nsxt_compute_collection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/* Copyright © 2023 VMware, Inc. All Rights Reserved.
SPDX-License-Identifier: MPL-2.0 */

package nsxt

import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/fabric"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/model"
)

func dataSourceNsxtComputeCollection() *schema.Resource {
return &schema.Resource{
Read: dataSourceNsxtComputeCollectionRead,

Schema: map[string]*schema.Schema{
"id": getDataSourceIDSchema(),
"display_name": getDisplayNameSchema(),
"origin_type": {
Type: schema.TypeString,
Optional: true,
Description: "ComputeCollection type like VC_Cluster. Here the Compute Manager type prefix would help in differentiating similar named Compute Collection types from different Compute Managers",
},
"origin_id": {
Type: schema.TypeString,
Optional: true,
Description: "Id of the compute manager from where this Compute Collection was discovered",
},
"cm_local_id": {
Type: schema.TypeString,
Optional: true,
Description: "Local Id of the compute collection in the Compute Manager",
},
},
}
}

func nullIfEmpty(s string) *string {
if s == "" {
return nil
}
return &s
}

func dataSourceNsxtComputeCollectionRead(d *schema.ResourceData, m interface{}) error {
connector := getPolicyConnector(m)
client := fabric.NewComputeCollectionsClient(connector)
objID := d.Get("id").(string)

objName := nullIfEmpty(d.Get("display_name").(string))
objOrigin := nullIfEmpty(d.Get("origin_id").(string))
objType := nullIfEmpty(d.Get("origin_type").(string))
objLocalID := nullIfEmpty(d.Get("cm_local_id").(string))

var obj model.ComputeCollection

if objID != "" {
// Get by id
objGet, err := client.Get(objID)
if err != nil {
return fmt.Errorf("failed to read ComputeCollection %s: %v", objID, err)
}
obj = objGet
} else {
objList, err := client.List(objLocalID, nil, nil, objName, nil, nil, nil, objOrigin, objType, nil, nil, nil, nil)
if err != nil {
return fmt.Errorf("failed to read Compute Collections: %v", err)
} else if *objList.ResultCount == 0 {
return fmt.Errorf("no Compute Collections that matched the specified parameters found")
} else if *objList.ResultCount > 1 {
return fmt.Errorf("found multiple Compute Collections that matched specified parameters")
}
obj = objList.Results[0]
}

d.SetId(*obj.ExternalId)
d.Set("display_name", obj.DisplayName)
d.Set("origin_type", obj.OriginType)
d.Set("origin_id", obj.OriginId)
d.Set("cm_local_id", obj.CmLocalId)

return nil
}
40 changes: 40 additions & 0 deletions nsxt/data_source_nsxt_compute_collection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* Copyright © 2017 VMware, Inc. All Rights Reserved.
SPDX-License-Identifier: MPL-2.0 */

package nsxt

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccDataSourceNsxtComputeCollection_basic(t *testing.T) {
ComputeCollectionName := getComputeCollectionName()
testResourceName := "data.nsxt_compute_collection.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccOnlyLocalManager(t); testAccTestMP(t); testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccNSXComputeCollectionReadTemplate(ComputeCollectionName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(testResourceName, "display_name", ComputeCollectionName),
resource.TestCheckResourceAttr(testResourceName, "origin_type", "VC_Cluster"),
resource.TestCheckResourceAttrSet(testResourceName, "id"),
resource.TestCheckResourceAttrSet(testResourceName, "origin_id"),
resource.TestCheckResourceAttrSet(testResourceName, "cm_local_id"),
),
},
},
})
}

func testAccNSXComputeCollectionReadTemplate(name string) string {
return fmt.Sprintf(`
data "nsxt_compute_collection" "test" {
display_name = "%s"
}`, name)
}
21 changes: 11 additions & 10 deletions nsxt/policy_errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ import (
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
)

func isEmptyAPIError(apiError model.ApiError) bool {
return (apiError.ErrorCode == nil && apiError.ErrorMessage == nil)
}

func printAPIError(apiError model.ApiError) string {
if apiError.ErrorMessage != nil && apiError.ErrorCode != nil {
return fmt.Sprintf("%s (code %v)", *apiError.ErrorMessage, *apiError.ErrorCode)
Expand Down Expand Up @@ -81,18 +77,23 @@ func logVapiErrorData(message string, vapiMessages []std.LocalizableMessage, vap
return fmt.Errorf("%s (no additional details provided)", message)
}

// ApiError type is identical in all three relevant SDKs - policy, MP and GM
var typeConverter = bindings.NewTypeConverter()
data, err := typeConverter.ConvertToGolang(apiErrorDataValue, model.ApiErrorBindingType())

// As of today, we cannot trust converter to return error in case target type doesn't
// match the actual error. This issue is being looked into on VAPI level.
// For now, we check both conversion error and actual contents of converted struct
if err != nil || isEmptyAPIError(data.(model.ApiError)) {
if err != nil {
// This is likely not an error coming from NSX
return logRawVapiErrorData(message, vapiType, apiErrorDataValue)
}

apiError := data.(model.ApiError)
apiError, ok := data.(model.ApiError)
if !ok {
// This is likely not an error coming from NSX
return logRawVapiErrorData(message, vapiType, apiErrorDataValue)
}

details := fmt.Sprintf(" %s: %s", message, printAPIError(apiError))

Expand Down Expand Up @@ -138,8 +139,8 @@ func isNotFoundError(err error) bool {
return false
}

func handleCreateError(resourceType string, resourceID string, err error) error {
msg := fmt.Sprintf("Failed to create %s %s", resourceType, resourceID)
func handleCreateError(resourceType string, resource string, err error) error {
msg := fmt.Sprintf("Failed to create %s %s", resourceType, resource)
return logAPIError(msg, err)
}

Expand All @@ -153,8 +154,8 @@ func handleListError(resourceType string, err error) error {
return logAPIError(msg, err)
}

func handleReadError(d *schema.ResourceData, resourceType string, resourceID string, err error) error {
msg := fmt.Sprintf("Failed to read %s %s", resourceType, resourceID)
func handleReadError(d *schema.ResourceData, resourceType string, resource string, err error) error {
msg := fmt.Sprintf("Failed to read %s %s", resourceType, resource)
if isNotFoundError(err) {
d.SetId("")
log.Print(msg)
Expand Down
35 changes: 22 additions & 13 deletions nsxt/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ func Provider() *schema.Provider {
"nsxt_compute_manager": dataSourceNsxtComputeManager(),
"nsxt_transport_node_realization": dataSourceNsxtTransportNodeRealization(),
"nsxt_failure_domain": dataSourceNsxtFailureDomain(),
"nsxt_compute_collection": dataSourceNsxtComputeCollection(),
},

ResourcesMap: map[string]*schema.Resource{
Expand Down Expand Up @@ -702,17 +703,21 @@ func configurePolicyConnectorData(d *schema.ResourceData, clients *nsxtClients)
return nil
}

err = configureLicenses(getPolicyConnector(*clients), clients.CommonConfig.LicenseDiff)
if err != nil {
return err
if !isVMC {
err = configureLicenses(getPolicyConnectorForInit(*clients), clients.CommonConfig.LicenseDiff)
if err != nil {
return err
}
}

if isVMC {
// Special treatment for VMC since MP API is not available there
err = initNSXVersion(getPolicyConnectorForInit(*clients))
if err != nil && isVMC {
// In case version API does not work for VMC, we workaround by testing version-specific APIs
// TODO - remove this when /node/version API works for all auth methods on VMC
initNSXVersionVMC(*clients)
return nil
}
return initNSXVersion(getPolicyConnector(*clients))
return err
}

func getConfiguredSecurityContext(clients *nsxtClients, vmcAccessToken string, vmcAuthHost string, vmcAuthMode string, username string, password string) (*core.SecurityContextImpl, error) {
Expand All @@ -727,10 +732,10 @@ func getConfiguredSecurityContext(clients *nsxtClients, vmcAccessToken string, v
return nil, err
}

if vmcAuthMode == "Bearer" {
clients.CommonConfig.BearerToken = apiToken
} else {

// We'll be sending Bearer token anyway even with scp-auth-token auth
// For now, node API is not working on VMC without Bearer token present
clients.CommonConfig.BearerToken = apiToken
if vmcAuthMode != "Bearer" {
securityCtx.SetProperty(security.AUTHENTICATION_SCHEME_ID, security.OAUTH_SCHEME_ID)
securityCtx.SetProperty(security.ACCESS_TOKEN, apiToken)
}
Expand Down Expand Up @@ -958,10 +963,14 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
}

func getPolicyConnector(clients interface{}) client.Connector {
return getPolicyConnectorWithHeaders(clients, nil)
return getPolicyConnectorWithHeaders(clients, nil, false)
}

func getPolicyConnectorForInit(clients interface{}) client.Connector {
return getPolicyConnectorWithHeaders(clients, nil, true)
}

func getPolicyConnectorWithHeaders(clients interface{}, customHeaders *map[string]string) client.Connector {
func getPolicyConnectorWithHeaders(clients interface{}, customHeaders *map[string]string, initFlow bool) client.Connector {
c := clients.(nsxtClients)

retryFunc := func(retryContext retry.RetryContext) bool {
Expand Down Expand Up @@ -1039,7 +1048,7 @@ func getPolicyConnectorWithHeaders(clients interface{}, customHeaders *map[strin
connector := client.NewConnector(c.Host, connectorOptions...)
// Init NSX version on demand if not done yet
// This is also our indication to apply licenses, in case of delayed connection
if nsxVersion == "" {
if nsxVersion == "" && !initFlow {
initNSXVersion(connector)
err := configureLicenses(connector, c.CommonConfig.LicenseDiff)
if err != nil {
Expand Down
21 changes: 7 additions & 14 deletions nsxt/resource_nsxt_compute_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,7 @@ func resourceNsxtComputeManagerCreate(d *schema.ResourceData, m interface{}) err
setAsOidcProvider := d.Get("set_as_oidc_provider").(bool)
credential, err := getCredentialValues(d)
if err != nil {
// id isn't known yet
handleCreateError("ComputeManager", "", err)
return handleCreateError("ComputeManager", displayName, err)
}

obj := model.ComputeManager{
Expand All @@ -259,17 +258,12 @@ func resourceNsxtComputeManagerCreate(d *schema.ResourceData, m interface{}) err
SetAsOidcProvider: &setAsOidcProvider,
}

log.Printf("[INFO] Creating Compute Manager %s", displayName)
obj, err = client.Create(obj)
if err != nil {
id := ""
if obj.Id != nil {
id = *obj.Id
}
return handleCreateError("Compute Manager", id, err)
return handleCreateError("Compute Manager", displayName, err)
}

log.Printf("[INFO] Creating Compute Manager with ID %s", *obj.Id)

d.SetId(*obj.Id)
return resourceNsxtComputeManagerRead(d, m)
}
Expand Down Expand Up @@ -381,7 +375,7 @@ func resourceNsxtComputeManagerRead(d *schema.ResourceData, m interface{}) error

obj, err := client.Get(id)
if err != nil {
return fmt.Errorf("error during Compute Manager read: %v", err)
return handleReadError(d, "ComputeManager", id, err)
}

d.Set("revision", obj.Revision)
Expand Down Expand Up @@ -488,8 +482,7 @@ func resourceNsxtComputeManagerUpdate(d *schema.ResourceData, m interface{}) err
setAsOidcProvider := d.Get("set_as_oidc_provider").(bool)
credential, err := getCredentialValues(d)
if err != nil {
// id isn't known yet
handleCreateError("ComputeManager", "", err)
return handleUpdateError("ComputeManager", id, err)
}

obj := model.ComputeManager{
Expand All @@ -509,7 +502,7 @@ func resourceNsxtComputeManagerUpdate(d *schema.ResourceData, m interface{}) err

_, err = client.Update(id, obj)
if err != nil {
return fmt.Errorf("error during Compute Manager %s update: %v", id, err)
return handleUpdateError("ComputeManager", id, err)
}

return resourceNsxtComputeManagerRead(d, m)
Expand All @@ -527,7 +520,7 @@ func resourceNsxtComputeManagerDelete(d *schema.ResourceData, m interface{}) err

err := client.Delete(id)
if err != nil {
return fmt.Errorf("error during Compute Manager delete: %v", err)
return handleDeleteError("ComputeManager", id, err)
}
return nil
}
15 changes: 5 additions & 10 deletions nsxt/resource_nsxt_edge_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,12 @@ func resourceNsxtEdgeClusterCreate(d *schema.ResourceData, m interface{}) error
Members: members,
}

log.Printf("[INFO] Creating Edge Cluster with name %s", displayName)
obj, err := client.Create(obj)
if err != nil {
id := ""
if obj.Id != nil {
id = *obj.Id
}
return handleCreateError("Edge Cluster", id, err)
return handleCreateError("Edge Cluster", displayName, err)
}

log.Printf("[INFO] Creating Edge Cluster with ID %s", *obj.Id)

d.SetId(*obj.Id)
return resourceNsxtEdgeClusterRead(d, m)
}
Expand Down Expand Up @@ -175,7 +170,7 @@ func resourceNsxtEdgeClusterRead(d *schema.ResourceData, m interface{}) error {
client := nsx.NewEdgeClustersClient(connector)
obj, err := client.Get(id)
if err != nil {
return fmt.Errorf("error during Edge Cluster read: %v", err)
return handleReadError(d, "EdgeCluster", id, err)
}

d.Set("revision", obj.Revision)
Expand Down Expand Up @@ -253,7 +248,7 @@ func resourceNsxtEdgeClusterUpdate(d *schema.ResourceData, m interface{}) error

_, err := client.Update(id, obj)
if err != nil {
return fmt.Errorf("error during Edge Cluster %s update: %v", id, err)
return handleUpdateError("EdgeCluster", id, err)
}

return resourceNsxtEdgeClusterRead(d, m)
Expand All @@ -271,7 +266,7 @@ func resourceNsxtEdgeClusterDelete(d *schema.ResourceData, m interface{}) error

err := client.Delete(id)
if err != nil {
return fmt.Errorf("error during Edge Cluster delete: %v", err)
return handleDeleteError("EdgeCluster", id, err)
}
return nil
}
Loading

0 comments on commit b4b1d20

Please sign in to comment.