Skip to content

Commit

Permalink
Merge pull request #453 from Juniper/add-tests-to-bills-data-source
Browse files Browse the repository at this point in the history
add tests and fix problems found in testing
  • Loading branch information
bwJuniper authored Nov 15, 2023
2 parents 1f968b4 + 2ee6fc2 commit 4771882
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 7 deletions.
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.

0 comments on commit 4771882

Please sign in to comment.