Skip to content

Commit

Permalink
chore: fix nul pointer when datasource was not found
Browse files Browse the repository at this point in the history
  • Loading branch information
David MICHENEAU committed Nov 14, 2024
1 parent ff904b0 commit 1d24b65
Show file tree
Hide file tree
Showing 6 changed files with 364 additions and 276 deletions.
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ linters:
- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
- gocognit # Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
- godox # Tool for detection of FIXME, TODO and other comment keywords [fast: true, auto-fix: false]
- gomnd # An analyzer to detect magic numbers. [fast: true, auto-fix: false]
- lll # Reports long lines [fast: true, auto-fix: false]
- maintidx # maintidx measures the maintainability index of each function. [fast: true, auto-fix: false]
- nestif # Reports deeply nested if statements [fast: true, auto-fix: false]
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/edgegateway_nat_rule.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ resource "cloudavenue_edgegateway_nat_rule" "example-reflexive" {

### Required

- `external_address` (String) The external address for the NAT Rule. This must be supplied as a single IP or Network CIDR. For a DNAT rule, this is the external facing IP Address for incoming traffic. For an SNAT rule, this is the external facing IP Address for outgoing traffic. These IPs are typically allocated/suballocated IP Addresses on the Edge Gateway. For a REFLEXIVE rule, these are the external facing IPs.
- `internal_address` (String) The internal address for the NAT Rule. This must be supplied as a single IP or Network CIDR. For a DNAT rule, this is the internal IP address for incoming traffic. For an SNAT rule, this is the internal IP Address for outgoing traffic. For a REFLEXIVE rule, these are the internal IPs. These IPs are typically the Private IPs that are allocated to workloads.
- `name` (String) (ForceNew) The Name of the Nat Rule.
- `rule_type` (String) (ForceNew) Nat Rule type. Value must be one of: `DNAT` (Rule translates the external IP to an internal IP and is used for inbound traffic.), `NO_DNAT` (Prevents external IP translation.), `SNAT` (Translates an internal IP to an external IP and is used for outbound traffic.), `NO_SNAT` (Prevents internal IP translation.), `REFLEXIVE` (This translates an internal IP to an external IP and vice versa.).
Expand All @@ -73,6 +72,7 @@ resource "cloudavenue_edgegateway_nat_rule" "example-reflexive" {
- `edge_gateway_id` (String) (ForceNew) The ID of the Edge Gateway. Ensure that one and only one attribute from this collection is set : `edge_gateway_name`, `edge_gateway_id`.
- `edge_gateway_name` (String) (ForceNew) The Name of the Edge Gateway. Ensure that one and only one attribute from this collection is set : `edge_gateway_name`, `edge_gateway_id`.
- `enabled` (Boolean) Enable or Disable the Nat Rule. Value defaults to `true`.
- `external_address` (String) The external address for the NAT Rule. This must be supplied as a single IP or Network CIDR. For a DNAT rule, this is the external facing IP Address for incoming traffic. For an SNAT rule, this is the external facing IP Address for outgoing traffic. These IPs are typically allocated/suballocated IP Addresses on the Edge Gateway. For a REFLEXIVE rule, these are the external facing IPs. If the value of [`rule_type`](#rule_type) attribute is one of `NO_DNAT` or `NO_SNAT` this attribute is **NULL**.
- `firewall_match` (String) You can set a firewall match rule to determine how firewall is applied during NAT. Value must be one of: `MATCH_INTERNAL_ADDRESS` (Applies firewall rule to the internal address of a NAT rule.), `MATCH_EXTERNAL_ADDRESS` (Applies firewall rule to the external address of a NAT rule.), `BYPASS` (Skip applying firewall rule to NAT rule.).
- `priority` (Number) If an address has multiple NAT rule, you can assign these rule different priorities to determine the order in which they are applied. A lower value means a higher priority for this rule. Value defaults to `0`.
- `snat_destination_address` (String) The destination addresses to match in the SNAT Rule. This must be supplied as a single IP or Network CIDR. Providing no value for this field results in match with ANY destination network. If the value of [`rule_type`](#rule_type) attribute is one of `DNAT`, `NO_DNAT` or `REFLEXIVE` this attribute is **NULL**.
Expand Down
1 change: 1 addition & 0 deletions internal/provider/edgegw/nat_rule_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ func (r *natRuleResource) read(planOrState *NATRuleModel) (stateRefreshed *NATRu
}
if err != nil {
if govcd.ContainsNotFound(err) {
diags.AddError("Error NAT Rule Not Found", err.Error())
return nil, false, diags
}
diags.AddError("Error retrieving NAT Rule ID", err.Error())
Expand Down
6 changes: 5 additions & 1 deletion internal/provider/edgegw/nat_rule_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ func natRuleSchema(_ context.Context) superschema.Schema {
MarkdownDescription: "The external address for the NAT Rule. This must be supplied as a single IP or Network CIDR. For a DNAT rule, this is the external facing IP Address for incoming traffic. For an SNAT rule, this is the external facing IP Address for outgoing traffic. These IPs are typically allocated/suballocated IP Addresses on the Edge Gateway. For a REFLEXIVE rule, these are the external facing IPs.",
},
Resource: &schemaR.StringAttribute{
Required: true,
// Required: true,
Optional: true,
Validators: []validator.String{
fstringvalidator.NullIfAttributeIsOneOf(path.MatchRoot("rule_type"), []attr.Value{types.StringValue("NO_DNAT"), types.StringValue("NO_SNAT")}),
},
// TODO - Validator of IP or IP/CIDR
},
DataSource: &schemaD.StringAttribute{
Expand Down
73 changes: 57 additions & 16 deletions internal/testsacc/edgegw_nat_rule_datasource_test.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,73 @@
package testsacc

import (
"context"
"testing"

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

"github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/helpers/testsacc"
)

var _ testsacc.TestACC = &NATRuleDataSource{}

const (
NATRuleDataSourceName = testsacc.ResourceName("data.cloudavenue_edgegateway_nat_rule")
)

const testAccNATRuleDataSourceConfig = `
data "cloudavenue_edgegateway_nat_rule" "example" {
depends_on = [cloudavenue_edgegateway.example_with_vdc, cloudavenue_edgegateway_nat_rule.example]
edge_gateway_id = cloudavenue_edgegateway.example_with_vdc.id
name = "example-snat"
type NATRuleDataSource struct{}

func NewNATRuleDataSourceTest() testsacc.TestACC {
return &NATRuleDataSource{}
}
`

func TestAccNatRuleDataSource(t *testing.T) {
dataSourceName := "data.cloudavenue_edgegateway_nat_rule.example"
// GetResourceName returns the name of the resource.
func (r *NATRuleDataSource) GetResourceName() string {
return NATRuleDataSourceName.String()
}

func (r *NATRuleDataSource) DependenciesConfig() (resp testsacc.DependenciesConfigResponse) {
resp.Append(GetResourceConfig()[NATRuleResourceName]().GetDefaultConfig)
return
}

func (r *NATRuleDataSource) Tests(ctx context.Context) map[testsacc.TestName]func(ctx context.Context, resourceName string) testsacc.Test {
return map[testsacc.TestName]func(ctx context.Context, resourceName string) testsacc.Test{
// * Test One (with edge_gateway_id)
"example": func(_ context.Context, _ string) testsacc.Test {
return testsacc.Test{
// ! Create testing
Create: testsacc.TFConfig{
TFConfig: `
data "cloudavenue_edgegateway_nat_rule" "example" {
edge_gateway_id = cloudavenue_edgegateway.example.id
name = "example"
}`,
Checks: GetResourceConfig()[NATRuleResourceName]().GetDefaultChecks(),
},
}
},
// * Test Two (with edge_gateway_name)
"example_2": func(_ context.Context, _ string) testsacc.Test {
return testsacc.Test{
// ! Create testing
Create: testsacc.TFConfig{
TFConfig: `
data "cloudavenue_edgegateway_nat_rule" "example" {
edge_gateway_name = cloudavenue_edgegateway.example.name
name = "example"
}`,
Checks: GetResourceConfig()[NATRuleResourceName]().GetDefaultChecks(),
},
}
},
}
}

func TestAccNATRuleDataSource(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { TestAccPreCheck(t) },
ProtoV6ProviderFactories: TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Read testing
{
// Apply test
Config: ConcatTests(testAccNATRuleResourceConfigSnat, testAccNATRuleDataSourceConfig, testAccEdgeGatewayResourceConfig),
Check: natRuleSnatTestCheck(dataSourceName),
},
},
Steps: testsacc.GenerateTests(&NATRuleDataSource{}),
})
}
Loading

0 comments on commit 1d24b65

Please sign in to comment.