Skip to content

Commit

Permalink
fix: bad ID returned in datasource app_port_profile
Browse files Browse the repository at this point in the history
  • Loading branch information
azrod committed Nov 29, 2024
1 parent 8a66a86 commit 58a3b8b
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 94 deletions.
7 changes: 7 additions & 0 deletions .changelog/849.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:bug
`datasource/cloudavenue_edgegateway_app_port_profile` - Fixed the issue where the `cloudavenue_edgegateway_app_port_profile` datasource was not returning the correct value App Port Profile ID.
```

```release-note:breaking-change
`datasource/cloudavenue_edgegateway_app_port_profile` - Now the datasource require one of the following attributes to be set: `edge_gateway_id` or `edge_gateway_name`.
```
2 changes: 2 additions & 0 deletions docs/data-sources/edgegateway_app_port_profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ data "cloudavenue_edgegateway_app_port_profile" "example" {

### Optional

- `edge_gateway_id` (String) ID of the Edge Gateway. Ensure that one and only one attribute from this collection is set : `edge_gateway_id`, `edge_gateway_name`.
- `edge_gateway_name` (String) Name of the Edge Gateway. Ensure that one and only one attribute from this collection is set : `edge_gateway_id`, `edge_gateway_name`.
- `id` (String) The ID of the App Port profile. Ensure that one and only one attribute from this collection is set : `name`, `id`.
- `name` (String) Application Port Profile name. Ensure that one and only one attribute from this collection is set : `name`, `id`.

Expand Down
44 changes: 24 additions & 20 deletions internal/provider/edgegw/app_port_profile_datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
"fmt"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/hashicorp/terraform-plugin-framework/datasource"

supertypes "github.com/FrangipaneTeam/terraform-plugin-framework-supertypes"

"github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client"
"github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/metrics"
"github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/common/edgegw"
"github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/common/org"
)

Expand All @@ -27,11 +27,28 @@ func NewAppPortProfileDataSource() datasource.DataSource {
type appPortProfileDataSource struct {
client *client.CloudAvenue
org org.Org
edgegw edgegw.EdgeGateway
}

// Init Initializes the data source.
func (d *appPortProfileDataSource) Init(ctx context.Context, dm *AppPortProfileModelADatasource) (diags diag.Diagnostics) {
func (d *appPortProfileDataSource) Init(ctx context.Context, dm *AppPortProfileModel) (diags diag.Diagnostics) {
var err error

d.org, diags = org.Init(d.client)
if diags.HasError() {
return
}

// Retrieve VDC from edge gateway
d.edgegw, err = d.org.GetEdgeGateway(edgegw.BaseEdgeGW{
ID: types.StringValue(dm.EdgeGatewayID.Get()),
Name: types.StringValue(dm.EdgeGatewayName.Get()),
})
if err != nil {
diags.AddError("Error retrieving Edge Gateway", err.Error())
return
}

return
}

Expand Down Expand Up @@ -63,8 +80,7 @@ func (d *appPortProfileDataSource) Configure(ctx context.Context, req datasource
func (d *appPortProfileDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
defer metrics.New("data.cloudavenue_edgegateway_app_port_profile", d.client.GetOrgName(), metrics.Read)()

config := &AppPortProfileModelADatasource{}

config := &AppPortProfileModel{}
// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, config)...)
if resp.Diagnostics.HasError() {
Expand All @@ -85,17 +101,11 @@ func (d *appPortProfileDataSource) Read(ctx context.Context, req datasource.Read
s := &appPortProfileResource{
client: d.client,
org: d.org,
edgegw: d.edgegw,
}

// Read data from the API
data, found, diags := s.read(ctx, &AppPortProfileModel{
ID: config.ID,
Name: config.Name,
Description: config.Description,
EdgeGatewayID: supertypes.NewStringNull(),
EdgeGatewayName: supertypes.NewStringNull(),
AppPorts: config.AppPorts,
})
configRefreshed, found, diags := s.read(ctx, config)
if !found {
if config.ID.IsKnown() {
resp.Diagnostics.AddError("Not found", fmt.Sprintf("App Port Profile ID %q not found", config.ID))
Expand All @@ -109,12 +119,6 @@ func (d *appPortProfileDataSource) Read(ctx context.Context, req datasource.Read
return
}

// Write data into the model
config.ID = data.ID
config.Name = data.Name
config.Description = data.Description
config.AppPorts = data.AppPorts

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...)
resp.Diagnostics.Append(resp.State.Set(ctx, &configRefreshed)...)
}
108 changes: 42 additions & 66 deletions internal/provider/edgegw/app_port_profile_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package edgegw
import (
"context"
"fmt"
"net/url"
"strings"

"github.com/vmware/go-vcloud-director/v2/govcd"
Expand Down Expand Up @@ -31,11 +32,28 @@ func NewAppPortProfileResource() resource.Resource {
type appPortProfileResource struct {
client *client.CloudAvenue
org org.Org
edgegw edgegw.EdgeGateway
}

// Init Initializes the resource.
func (r *appPortProfileResource) Init(ctx context.Context, rm *AppPortProfileModel) (diags diag.Diagnostics) {
var err error

r.org, diags = org.Init(r.client)
if diags.HasError() {
return
}

// Retrieve VDC from edge gateway
r.edgegw, err = r.org.GetEdgeGateway(edgegw.BaseEdgeGW{
ID: types.StringValue(rm.EdgeGatewayID.Get()),
Name: types.StringValue(rm.EdgeGatewayName.Get()),
})
if err != nil {
diags.AddError("Error retrieving Edge Gateway", err.Error())
return
}

return
}

Expand Down Expand Up @@ -88,17 +106,7 @@ func (r *appPortProfileResource) Create(ctx context.Context, req resource.Create
Implement the resource creation logic here.
*/

// Retrieve VDC from edge gateway
edgegw, err := r.org.GetEdgeGateway(edgegw.BaseEdgeGW{
ID: types.StringValue(plan.EdgeGatewayID.Get()),
Name: types.StringValue(plan.EdgeGatewayName.Get()),
})
if err != nil {
resp.Diagnostics.AddError("Error retrieving Edge Gateway", err.Error())
return
}

vdcOrVDCGroup, err := edgegw.GetParent()
vdcOrVDCGroup, err := r.edgegw.GetParent()
if err != nil {
resp.Diagnostics.AddError("Error retrieving Edge Gateway parent", err.Error())
return
Expand All @@ -124,8 +132,8 @@ func (r *appPortProfileResource) Create(ctx context.Context, req resource.Create
}

plan.ID.Set(appPortProfile.NsxtAppPortProfile.ID)
plan.EdgeGatewayID.Set(edgegw.GetID())
plan.EdgeGatewayName.Set(edgegw.GetName())
plan.EdgeGatewayID.Set(r.edgegw.GetID())
plan.EdgeGatewayName.Set(r.edgegw.GetName())
state, found, d := r.read(ctx, plan)
if !found {
resp.State.RemoveResource(ctx)
Expand Down Expand Up @@ -274,12 +282,6 @@ func (r *appPortProfileResource) ImportState(ctx context.Context, req resource.I

var d diag.Diagnostics

r.org, d = org.Init(r.client)
if d.HasError() {
resp.Diagnostics.Append(d...)
return
}

// split req.ID into edge gateway ID and app port profile ID/name
split := strings.Split(req.ID, ".")
if len(split) != 2 {
Expand Down Expand Up @@ -307,19 +309,11 @@ func (r *appPortProfileResource) ImportState(ctx context.Context, req resource.I
x.Name.Set(appPortProfileIDOrName)
}

// Retrieve VDC from edge gateway
edgegw, err := r.org.GetEdgeGateway(edgegw.BaseEdgeGW{
ID: types.StringValue(x.EdgeGatewayID.Get()),
Name: types.StringValue(x.EdgeGatewayName.Get()),
})
if err != nil {
resp.Diagnostics.AddError("Error retrieving Edge Gateway", err.Error())
resp.Diagnostics.Append(r.Init(ctx, x)...)
if resp.Diagnostics.HasError() {
return
}

x.EdgeGatewayID.Set(edgegw.GetID())
x.EdgeGatewayName.Set(edgegw.GetName())

stateRefreshed, found, d := r.read(ctx, x)
if !found {
resp.State.RemoveResource(ctx)
Expand Down Expand Up @@ -347,51 +341,31 @@ func (r *appPortProfileResource) read(ctx context.Context, planOrState *AppPortP
if planOrState.ID.IsKnown() {
appPortProfile, err = r.org.GetNsxtAppPortProfileById(stateRefreshed.ID.Get())
} else {
appPortProfilesTenant, erR := r.org.GetAllNsxtAppPortProfiles(nil, govcdtypes.ApplicationPortProfileScopeTenant)
if erR != nil {
diags.AddError("Error reading App Port Profiles", erR.Error())
return
}

for _, singleAppPortProfile := range appPortProfilesTenant {
if singleAppPortProfile.NsxtAppPortProfile.Name == stateRefreshed.Name.Get() {
appPortProfile = singleAppPortProfile
break
}
}

if appPortProfile == nil {
appPortProfilesProvider, erR := r.org.GetAllNsxtAppPortProfiles(nil, govcdtypes.ApplicationPortProfileScopeProvider)
if erR != nil {
diags.AddError("Error reading App Port Profiles", erR.Error())
return
}
scopes := []string{govcdtypes.ApplicationPortProfileScopeTenant, govcdtypes.ApplicationPortProfileScopeProvider, govcdtypes.ApplicationPortProfileScopeSystem}

for _, singleAppPortProfile := range appPortProfilesProvider {
if singleAppPortProfile.NsxtAppPortProfile.Name == stateRefreshed.Name.Get() {
appPortProfile = singleAppPortProfile
break
}
}
vdcOrVDCGroup, err := r.edgegw.GetParent()
if err != nil {
diags.AddError("Error retrieving Edge Gateway parent", err.Error())
return
}

if appPortProfile == nil {
appPortProfilesSystem, erR := r.org.GetAllNsxtAppPortProfiles(nil, govcdtypes.ApplicationPortProfileScopeSystem)
if erR != nil {
diags.AddError("Error reading App Port Profiles", erR.Error())
return
}

for _, singleAppPortProfile := range appPortProfilesSystem {
if singleAppPortProfile.NsxtAppPortProfile.Name == stateRefreshed.Name.Get() {
appPortProfile = singleAppPortProfile
break
for _, scope := range scopes {
queryParams := url.Values{}
queryParams.Add("filter", fmt.Sprintf("name==%s;scope==%s;_context==%s", stateRefreshed.Name.Get(), scope, vdcOrVDCGroup.GetID()))
appPortProfiles, _ := r.org.GetAllNsxtAppPortProfiles(queryParams, "")
// Error is ignored because we want to continue searching in other scopes if not found
if len(appPortProfiles) > 0 {
if len(appPortProfiles) > 1 {
diags.AddError("Error reading App Port Profiles", fmt.Sprintf("expected exactly one Application Port Profile with name '%s'. Got %d", stateRefreshed.Name.Get(), len(appPortProfiles)))
return
}
appPortProfile = appPortProfiles[0]
break
}
}

if appPortProfile == nil {
err = govcd.ErrorEntityNotFound
return nil, false, nil
}
}

Expand Down Expand Up @@ -427,6 +401,8 @@ func (r *appPortProfileResource) read(ctx context.Context, planOrState *AppPortP
stateRefreshed.Name.Set(appPortProfile.NsxtAppPortProfile.Name)
stateRefreshed.Description.Set(appPortProfile.NsxtAppPortProfile.Description)
stateRefreshed.AppPorts.Set(ctx, appPorts)
stateRefreshed.EdgeGatewayID.Set(r.edgegw.GetID())
stateRefreshed.EdgeGatewayName.Set(r.edgegw.GetName())

return stateRefreshed, true, nil
}
8 changes: 6 additions & 2 deletions internal/provider/edgegw/app_port_profile_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,26 +78,30 @@ func appPortProfilesSchema(_ context.Context) superschema.Schema {
},
},
"edge_gateway_id": superschema.SuperStringAttribute{
Resource: &schemaR.StringAttribute{
Common: &schemaR.StringAttribute{
MarkdownDescription: "ID of the Edge Gateway.",
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.ExactlyOneOf(path.MatchRoot("edge_gateway_id"), path.MatchRoot("edge_gateway_name")),
},
},
Resource: &schemaR.StringAttribute{
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplaceIfConfigured(),
},
},
},
"edge_gateway_name": superschema.SuperStringAttribute{
Resource: &schemaR.StringAttribute{
Common: &schemaR.StringAttribute{
MarkdownDescription: "Name of the Edge Gateway.",
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.ExactlyOneOf(path.MatchRoot("edge_gateway_id"), path.MatchRoot("edge_gateway_name")),
},
},
Resource: &schemaR.StringAttribute{
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplaceIfConfigured(),
},
Expand Down
12 changes: 6 additions & 6 deletions internal/provider/edgegw/app_port_profile_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ type AppPortProfileModel struct {
AppPorts supertypes.ListNestedObjectValueOf[AppPortProfileModelAppPort] `tfsdk:"app_ports"`
}

type AppPortProfileModelADatasource struct {
ID supertypes.StringValue `tfsdk:"id"`
Name supertypes.StringValue `tfsdk:"name"`
Description supertypes.StringValue `tfsdk:"description"`
AppPorts supertypes.ListNestedObjectValueOf[AppPortProfileModelAppPort] `tfsdk:"app_ports"`
}
// type AppPortProfileModelADatasource struct {
// ID supertypes.StringValue `tfsdk:"id"`
// Name supertypes.StringValue `tfsdk:"name"`
// Description supertypes.StringValue `tfsdk:"description"`
// AppPorts supertypes.ListNestedObjectValueOf[AppPortProfileModelAppPort] `tfsdk:"app_ports"`
// }

type AppPortProfileModelAppPort struct {
Protocol supertypes.StringValue `tfsdk:"protocol"`
Expand Down
Loading

0 comments on commit 58a3b8b

Please sign in to comment.