Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tests and fix problems found in testing #453

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apstra/blueprint/datacenter_virtual_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (o DatacenterVirtualNetwork) DataSourceAttributes() map[string]dataSourceSc
MarkdownDescription: "Details availability of the virtual network on leaf and access switches",
Computed: true,
NestedObject: dataSourceSchema.NestedAttributeObject{
Attributes: map[string]dataSourceSchema.Attribute{},
Attributes: VnBinding{}.DataSourceAttributes(),
},
},
"dhcp_service_enabled": dataSourceSchema.BoolAttribute{
Expand Down
17 changes: 16 additions & 1 deletion apstra/blueprint/vn_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ func (o VnBinding) attrTypes() map[string]attr.Type {

}

func (o VnBinding) DataSourceAttributes() map[string]dataSourceSchema.Attribute {
return map[string]dataSourceSchema.Attribute{
"vlan_id": dataSourceSchema.Int64Attribute{
MarkdownDescription: "VLAN id on the specified switch, switch pair and access switches.",
Computed: true,
},
"access_ids": dataSourceSchema.SetAttribute{
MarkdownDescription: "A set of zero or more graph db node IDs representing Access " +
"Switch `system` nodes or a `redundancy_group` nodes.",
Computed: true,
ElementType: types.StringType,
},
}
}

func (o VnBinding) DataSourceAttributesConstructorOutput() map[string]dataSourceSchema.Attribute {
return map[string]dataSourceSchema.Attribute{
"vlan_id": dataSourceSchema.Int64Attribute{
Expand All @@ -37,7 +52,7 @@ func (o VnBinding) DataSourceAttributesConstructorOutput() map[string]dataSource
},
"access_ids": dataSourceSchema.SetAttribute{
MarkdownDescription: "A set of zero or more graph db node IDs representing Access " +
"Lwitch `system` nodes or a `redundancy_group` nodes.",
"Switch `system` nodes or a `redundancy_group` nodes.",
Computed: true,
ElementType: types.StringType,
},
Expand Down
4 changes: 2 additions & 2 deletions apstra/data_source_datacenter_external_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestDatacenterExternalGateway(t *testing.T) {
RouteTypes: apstra.RemoteGatewayRouteTypesAll,
LocalGwNodes: leafIds,
GwAsn: rand.Uint32(),
GwIp: randIpAddressMust(t, "10.0.0.0/8"),
GwIp: randIpv4AddressMust(t, "10.0.0.0/8"),
GwName: acctest.RandString(5),
Ttl: &ttl,
KeepaliveTimer: &keepalive,
Expand All @@ -69,7 +69,7 @@ func TestDatacenterExternalGateway(t *testing.T) {
RouteTypes: apstra.RemoteGatewayRouteTypesFiveOnly,
LocalGwNodes: leafIds,
GwAsn: rand.Uint32(),
GwIp: randIpAddressMust(t, "10.0.0.0/8"),
GwIp: randIpv4AddressMust(t, "10.0.0.0/8"),
GwName: acctest.RandString(5),
Ttl: &ttl,
KeepaliveTimer: &keepalive,
Expand Down
2 changes: 2 additions & 0 deletions apstra/data_source_datacenter_virtual_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var _ datasource.DataSourceWithConfigure = &dataSourceDatacenterVirtualNetwork{}
Expand Down Expand Up @@ -79,6 +80,7 @@ func (o *dataSourceDatacenterVirtualNetwork) Read(ctx context.Context, req datas
}

// load the API response and set the state
config.Id = types.StringValue(api.Id.String())
config.LoadApiData(ctx, api.Data, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
Expand Down
135 changes: 135 additions & 0 deletions apstra/data_source_datacenter_virtual_network_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package tfapstra_test

import (
"context"
"errors"
"fmt"
"github.com/Juniper/apstra-go-sdk/apstra"
testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils"
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"testing"
)

const (
dataSourceDataCenterVirtualNetworkByIdHcl = `
data "apstra_datacenter_virtual_network" "test" {
blueprint_id = "%s"
id = "%s"
}
`

dataSourceDataCenterVirtualNetworkByNameHcl = `
data "apstra_datacenter_virtual_network" "test" {
blueprint_id = "%s"
name = "%s"
}
`
)

func TestDatacenterVirtualNetwork(t *testing.T) {
ctx := context.Background()

// create a test blueprint
bp, bpDelete, err := testutils.BlueprintA(ctx)
if err != nil {
t.Fatal(errors.Join(err, bpDelete(ctx)))
}
defer func() {
err = bpDelete(ctx)
if err != nil {
t.Error(err)
}
}()

// create a security zone within the blueprint
name := acctest.RandString(5)
zoneId, err := bp.CreateSecurityZone(ctx, &apstra.SecurityZoneData{
SzType: apstra.SecurityZoneTypeEVPN,
VrfName: name,
Label: name,
})
if err != nil {
t.Fatal(err)
}

// grab some data we'll need when creating virtual networks
leafIdStrings := systemIds(ctx, t, bp, "leaf")
vnBindings := make([]apstra.VnBinding, len(leafIdStrings))
for i, id := range leafIdStrings {
vnBindings[i] = apstra.VnBinding{SystemId: apstra.ObjectId(id)}
}

// specify virtual networks we want to create (and ultimately test the data source against)
virtualNetworks := []apstra.VirtualNetwork{
{
Data: &apstra.VirtualNetworkData{
Ipv4Enabled: true,
Ipv4Subnet: randIpv4NetMust(t, "10.0.0.0/16"),
Label: acctest.RandString(5),
SecurityZoneId: zoneId,
VnType: apstra.VnTypeVxlan,
VnBindings: vnBindings,
},
},
{
Data: &apstra.VirtualNetworkData{
Ipv4Enabled: true,
Ipv4Subnet: randIpv4NetMust(t, "10.1.0.0/16"),
Label: acctest.RandString(5),
SecurityZoneId: zoneId,
VnType: apstra.VnTypeVlan,
VnBindings: []apstra.VnBinding{{SystemId: apstra.ObjectId(leafIdStrings[0])}},
},
},
}

// create the test virtual networks
for i := range virtualNetworks {
virtualNetworks[i].Id, err = bp.CreateVirtualNetwork(ctx, virtualNetworks[i].Data)
if err != nil {
t.Fatal(err)
}
}

genTestCheckFuncs := func(vn apstra.VirtualNetwork) []resource.TestCheckFunc {
result := []resource.TestCheckFunc{
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "id", vn.Id.String()),
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "blueprint_id", bp.Id().String()),
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "name", vn.Data.Label),
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "type", vn.Data.VnType.String()),
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "ipv4_connectivity_enabled", fmt.Sprintf("%t", vn.Data.Ipv4Enabled)),
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "ipv4_virtual_gateway_enabled", fmt.Sprintf("%t", vn.Data.VirtualGatewayIpv4Enabled)),
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "ipv6_connectivity_enabled", fmt.Sprintf("%t", vn.Data.Ipv6Enabled)),
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "ipv6_virtual_gateway_enabled", fmt.Sprintf("%t", vn.Data.VirtualGatewayIpv6Enabled)),
resource.TestCheckResourceAttr("data.apstra_datacenter_virtual_network.test", "bindings.%", fmt.Sprintf("%d", len(vn.Data.VnBindings))),
}
return result
}

testCheckFuncsByVnId := make(map[apstra.ObjectId][]resource.TestCheckFunc, len(virtualNetworks))
for _, virtualNetwork := range virtualNetworks {
testCheckFuncsByVnId[virtualNetwork.Id] = genTestCheckFuncs(virtualNetwork)
}

stepsById := make([]resource.TestStep, len(virtualNetworks))
for i, virtualNetwork := range virtualNetworks {
stepsById[i] = resource.TestStep{
Config: insecureProviderConfigHCL + fmt.Sprintf(dataSourceDataCenterVirtualNetworkByIdHcl, bp.Id(), virtualNetwork.Id),
Check: resource.ComposeAggregateTestCheckFunc(testCheckFuncsByVnId[virtualNetwork.Id]...),
}
}

stepsByName := make([]resource.TestStep, len(virtualNetworks))
for i, virtualNetwork := range virtualNetworks {
stepsByName[i] = resource.TestStep{
Config: insecureProviderConfigHCL + fmt.Sprintf(dataSourceDataCenterVirtualNetworkByNameHcl, bp.Id(), virtualNetwork.Data.Label),
Check: resource.ComposeAggregateTestCheckFunc(genTestCheckFuncs(virtualNetwork)...),
}
}

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: append(stepsById, stepsByName...),
})
}
17 changes: 15 additions & 2 deletions apstra/test_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/Juniper/apstra-go-sdk/apstra"
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"golang.org/x/exp/constraints"
"math/rand"
"net"
"testing"
)
Expand Down Expand Up @@ -70,15 +71,27 @@ func intPtrOrNull[A constraints.Integer](in *A) string {
// return `"` + in.String() + `"`
//}

func randIpAddressMust(t *testing.T, cidrBlock string) net.IP {
func randIpv4NetMust(t *testing.T, cidrBlock string) *net.IPNet {
ip := randIpv4AddressMust(t, cidrBlock)

_, ipNet, _ := net.ParseCIDR(cidrBlock)
cidrBlockPrefixLen, _ := ipNet.Mask.Size()
targetPrefixLen := rand.Intn(31-cidrBlockPrefixLen) + cidrBlockPrefixLen

_, result, _ := net.ParseCIDR(fmt.Sprintf("%s/%d", ip.String(), targetPrefixLen))

return result
}

func randIpv4AddressMust(t *testing.T, cidrBlock string) net.IP {
s, err := acctest.RandIpAddress(cidrBlock)
if err != nil {
t.Fatal(err)
}

ip := net.ParseIP(s)
if ip == nil {
t.Fatalf("randIpAddressMust failed to parse IP address %q", s)
t.Fatalf("randIpv4AddressMust failed to parse IP address %q", s)
}

return ip
Expand Down
5 changes: 5 additions & 0 deletions docs/data-sources/datacenter_virtual_network.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,8 @@ locals {

<a id="nestedatt--bindings"></a>
### Nested Schema for `bindings`

Read-Only:

- `access_ids` (Set of String) A set of zero or more graph db node IDs representing Access Switch `system` nodes or a `redundancy_group` nodes.
- `vlan_id` (Number) VLAN id on the specified switch, switch pair and access switches.
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,5 @@ data "apstra_datacenter_virtual_network_binding_constructor" "example" {

Read-Only:

- `access_ids` (Set of String) A set of zero or more graph db node IDs representing Access Lwitch `system` nodes or a `redundancy_group` nodes.
- `access_ids` (Set of String) A set of zero or more graph db node IDs representing Access Switch `system` nodes or a `redundancy_group` nodes.
- `vlan_id` (Number) The value supplied as `vlan_id` at the root of this datasource configuration, if any. May be `null`, in which case Apstra will choose.