terraform-provider-stackitp.../stackit/internal/services/iaas/iaas_acc_test.go
GokceGK b58bd0f640
Onboard iaas network area (#500)
* Onboard network-area resource (#469)

* onboard network-area resource

* fix update network ranges

* fix linter issues

* add organization id to test util

* add examples

* change project count to computed and adapt unit tests

* extend acceptance tests

* add docs

* fix linter issues

* add datasource to provider

* remove routes from the datasource schema

* remove obsolete api cals

* remove raw response from create network area

* change network ranges to list of objects

* update examples

* fix linter issues

* Update stackit/internal/services/iaas/networkarea/resource.go

Co-authored-by: João Palet <joao.palet@outlook.com>

* add network range id to schema

* map network_range_id

* fix unit tests

* adapt acceptance test

* fix acceptance tests

* Update stackit/internal/services/iaas/iaas_acc_test.go

Co-authored-by: João Palet <joao.palet@outlook.com>

---------

Co-authored-by: João Palet <joao.palet@outlook.com>

* Add network area to beta resources list (#481)

* add network area to beta resources list

* add accidentally removed line

* add accidentally removed line

* Fix multi range creation issue (#483)

* fix multi range creation issue

* fix network range update issue

* fix some unit tests

* fix order issue

* Update stackit/internal/services/iaas/networkarea/resource.go

Co-authored-by: João Palet <joao.palet@outlook.com>

* add unit test to cover the reconciled list

---------

Co-authored-by: João Palet <joao.palet@outlook.com>

* Onboard IaaS network area route (#491)

* onboard network area route

* generate docs

* add route to beta resources

* extend acceptance test

* fix import id handling

* Update next_hop description

Co-authored-by: João Palet <joao.palet@outlook.com>

* Update prefix description

Co-authored-by: João Palet <joao.palet@outlook.com>

* change descriptions in datasource

* add IP and CIDR validators

* use requiresReplace in resource

* improve error logs

* change the create response handling

* update docs

* change route and route id detection

---------

Co-authored-by: João Palet <joao.palet@outlook.com>

---------

Co-authored-by: João Palet <joao.palet@outlook.com>
2024-08-09 12:38:35 +02:00

372 lines
14 KiB
Go

package iaas_test
import (
"context"
"fmt"
"strings"
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/stackitcloud/stackit-sdk-go/core/config"
"github.com/stackitcloud/stackit-sdk-go/core/utils"
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/testutil"
)
// Network resource data
var networkResource = map[string]string{
"project_id": testutil.ProjectId,
"name": fmt.Sprintf("acc-test-%s", acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)),
"ipv4_prefix_length": "24",
"nameserver0": "1.2.3.4",
"nameserver1": "5.6.7.8",
}
var networkAreaResource = map[string]string{
"organization_id": testutil.OrganizationId,
"name": fmt.Sprintf("acc-test-%s", acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)),
"networkrange0": "10.0.0.0/16",
"transfer_network": "10.1.2.0/24",
}
var networkAreaRouteResource = map[string]string{
"organization_id": networkAreaResource["organization_id"],
"network_area_id": networkAreaResource["network_area_id"],
"prefix": "1.1.1.0/24",
"next_hop": "1.1.1.1",
}
func networkResourceConfig(name, nameservers string) string {
return fmt.Sprintf(`
resource "stackit_network" "network" {
project_id = "%s"
name = "%s"
ipv4_prefix_length = "%s"
nameservers = %s
}
`,
networkResource["project_id"],
name,
networkResource["ipv4_prefix_length"],
nameservers,
)
}
func networkAreaResourceConfig(areaname, networkranges string) string {
return fmt.Sprintf(`
resource "stackit_network_area" "network_area" {
organization_id = "%s"
name = "%s"
network_ranges = [{
prefix = "%s"
}]
transfer_network = "%s"
}
`,
networkAreaResource["organization_id"],
areaname,
networkranges,
networkAreaResource["transfer_network"],
)
}
func networkAreaRouteResourceConfig() string {
return fmt.Sprintf(`
resource "stackit_network_area_route" "network_area_route" {
organization_id = stackit_network_area.network_area.organization_id
network_area_id = stackit_network_area.network_area.network_area_id
prefix = "%s"
next_hop = "%s"
}
`,
networkAreaRouteResource["prefix"],
networkAreaRouteResource["next_hop"],
)
}
func resourceConfig(name, nameservers, areaname, networkranges string) string {
return fmt.Sprintf("%s\n\n%s\n\n%s\n\n%s",
testutil.IaaSProviderConfig(),
networkResourceConfig(name, nameservers),
networkAreaResourceConfig(areaname, networkranges),
networkAreaRouteResourceConfig(),
)
}
func TestAccIaaS(t *testing.T) {
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
CheckDestroy: testAccCheckIaaSDestroy,
Steps: []resource.TestStep{
// Creation
{
Config: resourceConfig(
networkResource["name"],
fmt.Sprintf(
"[%q]",
networkResource["nameserver0"],
),
networkAreaResource["name"],
networkAreaResource["networkrange0"],
),
Check: resource.ComposeAggregateTestCheckFunc(
// Instance
resource.TestCheckResourceAttr("stackit_network.network", "project_id", networkResource["project_id"]),
resource.TestCheckResourceAttrSet("stackit_network.network", "network_id"),
resource.TestCheckResourceAttr("stackit_network.network", "name", networkResource["name"]),
resource.TestCheckResourceAttr("stackit_network.network", "nameservers.#", "1"),
resource.TestCheckResourceAttr("stackit_network.network", "nameservers.0", networkResource["nameserver0"]),
// Network Area
resource.TestCheckResourceAttr("stackit_network_area.network_area", "organization_id", networkAreaResource["organization_id"]),
resource.TestCheckResourceAttrSet("stackit_network_area.network_area", "network_area_id"),
resource.TestCheckResourceAttr("stackit_network_area.network_area", "name", networkAreaResource["name"]),
resource.TestCheckResourceAttr("stackit_network_area.network_area", "network_ranges.#", "1"),
resource.TestCheckResourceAttr("stackit_network_area.network_area", "network_ranges.0.prefix", networkAreaResource["networkrange0"]),
resource.TestCheckResourceAttrSet("stackit_network_area.network_area", "network_ranges.0.network_range_id"),
// Network Area Route
resource.TestCheckResourceAttrPair(
"stackit_network_area_route.network_area_route", "organization_id",
"stackit_network_area.network_area", "organization_id",
),
resource.TestCheckResourceAttrPair(
"stackit_network_area_route.network_area_route", "network_area_id",
"stackit_network_area.network_area", "network_area_id",
),
resource.TestCheckResourceAttrSet("stackit_network_area_route.network_area_route", "network_area_route_id"),
resource.TestCheckResourceAttr("stackit_network_area_route.network_area_route", "prefix", networkAreaRouteResource["prefix"]),
resource.TestCheckResourceAttr("stackit_network_area_route.network_area_route", "next_hop", networkAreaRouteResource["next_hop"]),
),
},
// Data source
{
Config: fmt.Sprintf(`
%s
data "stackit_network" "network" {
project_id = stackit_network.network.project_id
network_id = stackit_network.network.network_id
}
data "stackit_network_area" "network_area" {
organization_id = stackit_network_area.network_area.organization_id
network_area_id = stackit_network_area.network_area.network_area_id
}
data "stackit_network_area_route" "network_area_route" {
organization_id = stackit_network_area.network_area.organization_id
network_area_id = stackit_network_area.network_area.network_area_id
network_area_route_id = stackit_network_area_route.network_area_route.network_area_route_id
}
`,
resourceConfig(
networkResource["name"],
fmt.Sprintf(
"[%q]",
networkResource["nameserver0"],
),
networkAreaResource["name"],
networkAreaResource["networkrange0"],
),
),
Check: resource.ComposeAggregateTestCheckFunc(
// Instance
resource.TestCheckResourceAttr("data.stackit_network.network", "project_id", networkResource["project_id"]),
resource.TestCheckResourceAttrPair(
"stackit_network.network", "network_id",
"data.stackit_network.network", "network_id",
),
resource.TestCheckResourceAttr("data.stackit_network.network", "name", networkResource["name"]),
resource.TestCheckResourceAttr("data.stackit_network.network", "nameservers.0", networkResource["nameserver0"]),
// Network area
resource.TestCheckResourceAttr("data.stackit_network_area.network_area", "organization_id", networkAreaResource["organization_id"]),
resource.TestCheckResourceAttrPair(
"stackit_network_area.network_area", "network_area_id",
"data.stackit_network_area.network_area", "network_area_id",
),
resource.TestCheckResourceAttr("data.stackit_network_area.network_area", "name", networkAreaResource["name"]),
resource.TestCheckResourceAttr("data.stackit_network_area.network_area", "network_ranges.#", "1"),
resource.TestCheckResourceAttr("data.stackit_network_area.network_area", "network_ranges.0.prefix", networkAreaResource["networkrange0"]),
// Network area route
resource.TestCheckResourceAttrPair(
"stackit_network_area_route.network_area_route", "organization_id",
"stackit_network_area.network_area", "organization_id",
),
resource.TestCheckResourceAttrPair(
"stackit_network_area_route.network_area_route", "network_area_id",
"stackit_network_area.network_area", "network_area_id",
),
resource.TestCheckResourceAttrSet("stackit_network_area_route.network_area_route", "network_area_route_id"),
resource.TestCheckResourceAttr("stackit_network_area_route.network_area_route", "prefix", networkAreaRouteResource["prefix"]),
resource.TestCheckResourceAttr("stackit_network_area_route.network_area_route", "next_hop", networkAreaRouteResource["next_hop"]),
),
},
// Import
{
ResourceName: "stackit_network.network",
ImportStateIdFunc: func(s *terraform.State) (string, error) {
r, ok := s.RootModule().Resources["stackit_network.network"]
if !ok {
return "", fmt.Errorf("couldn't find resource stackit_network.network")
}
networkId, ok := r.Primary.Attributes["network_id"]
if !ok {
return "", fmt.Errorf("couldn't find attribute network_id")
}
return fmt.Sprintf("%s,%s", testutil.ProjectId, networkId), nil
},
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"ipv4_prefix_length"}, // Field is not returned by the API
},
{
ResourceName: "stackit_network_area.network_area",
ImportStateIdFunc: func(s *terraform.State) (string, error) {
r, ok := s.RootModule().Resources["stackit_network_area.network_area"]
if !ok {
return "", fmt.Errorf("couldn't find resource stackit_network_area.network_area")
}
networkAreaId, ok := r.Primary.Attributes["network_area_id"]
if !ok {
return "", fmt.Errorf("couldn't find attribute network_area_id")
}
return fmt.Sprintf("%s,%s", testutil.OrganizationId, networkAreaId), nil
},
ImportState: true,
ImportStateVerify: true,
},
{
ResourceName: "stackit_network_area_route.network_area_route",
ImportStateIdFunc: func(s *terraform.State) (string, error) {
r, ok := s.RootModule().Resources["stackit_network_area_route.network_area_route"]
if !ok {
return "", fmt.Errorf("couldn't find resource stackit_network_area_route.network_area_route")
}
networkAreaId, ok := r.Primary.Attributes["network_area_id"]
if !ok {
return "", fmt.Errorf("couldn't find attribute network_area_id")
}
networkAreaRouteId, ok := r.Primary.Attributes["network_area_route_id"]
if !ok {
return "", fmt.Errorf("couldn't find attribute network_area_route_id")
}
return fmt.Sprintf("%s,%s,%s", testutil.OrganizationId, networkAreaId, networkAreaRouteId), nil
},
ImportState: true,
ImportStateVerify: true,
},
// Update
{
Config: resourceConfig(
fmt.Sprintf("%s-updated", networkResource["name"]),
fmt.Sprintf(
"[%q, %q]",
networkResource["nameserver0"],
networkResource["nameserver1"],
),
fmt.Sprintf("%s-updated", networkAreaResource["name"]),
networkAreaResource["networkrange0"],
),
Check: resource.ComposeAggregateTestCheckFunc(
// Instance
resource.TestCheckResourceAttr("stackit_network.network", "project_id", networkResource["project_id"]),
resource.TestCheckResourceAttrSet("stackit_network.network", "network_id"),
resource.TestCheckResourceAttr("stackit_network.network", "name", fmt.Sprintf("%s-updated", networkResource["name"])),
resource.TestCheckResourceAttr("stackit_network.network", "nameservers.#", "2"),
resource.TestCheckResourceAttr("stackit_network.network", "nameservers.0", networkResource["nameserver0"]),
resource.TestCheckResourceAttr("stackit_network.network", "nameservers.1", networkResource["nameserver1"]),
// Network area
resource.TestCheckResourceAttr("stackit_network_area.network_area", "organization_id", networkAreaResource["organization_id"]),
resource.TestCheckResourceAttrSet("stackit_network_area.network_area", "network_area_id"),
resource.TestCheckResourceAttr("stackit_network_area.network_area", "name", fmt.Sprintf("%s-updated", networkAreaResource["name"])),
resource.TestCheckResourceAttr("stackit_network_area.network_area", "network_ranges.#", "1"),
resource.TestCheckResourceAttr("stackit_network_area.network_area", "network_ranges.0.prefix", networkAreaResource["networkrange0"]),
),
},
// Deletion is done by the framework implicitly
},
})
}
func testAccCheckIaaSDestroy(s *terraform.State) error {
ctx := context.Background()
var client *iaas.APIClient
var err error
if testutil.IaaSCustomEndpoint == "" {
client, err = iaas.NewAPIClient(
config.WithRegion("eu01"),
)
} else {
client, err = iaas.NewAPIClient(
config.WithEndpoint(testutil.IaaSCustomEndpoint),
)
}
if err != nil {
return fmt.Errorf("creating client: %w", err)
}
networksToDestroy := []string{}
for _, rs := range s.RootModule().Resources {
if rs.Type != "stackit_network" {
continue
}
// network terraform ID: "[project_id],[network_id]"
networkId := strings.Split(rs.Primary.ID, core.Separator)[1]
networksToDestroy = append(networksToDestroy, networkId)
}
networksResp, err := client.ListNetworksExecute(ctx, testutil.ProjectId)
if err != nil {
return fmt.Errorf("getting networksResp: %w", err)
}
networks := *networksResp.Items
for i := range networks {
if networks[i].NetworkId == nil {
continue
}
if utils.Contains(networksToDestroy, *networks[i].NetworkId) {
err := client.DeleteNetworkExecute(ctx, testutil.ProjectId, *networks[i].NetworkId)
if err != nil {
return fmt.Errorf("destroying network %s during CheckDestroy: %w", *networks[i].NetworkId, err)
}
}
}
// network areas
networkAreasToDestroy := []string{}
for _, rs := range s.RootModule().Resources {
if rs.Type != "stackit_network_area" {
continue
}
networkAreaId := strings.Split(rs.Primary.ID, core.Separator)[1]
networkAreasToDestroy = append(networkAreasToDestroy, networkAreaId)
}
networkAreasResp, err := client.ListNetworkAreasExecute(ctx, testutil.OrganizationId)
if err != nil {
return fmt.Errorf("getting networkAreasResp: %w", err)
}
networkAreas := *networkAreasResp.Items
for i := range networkAreas {
if networkAreas[i].AreaId == nil {
continue
}
if utils.Contains(networkAreasToDestroy, *networkAreas[i].AreaId) {
err := client.DeleteNetworkAreaExecute(ctx, testutil.OrganizationId, *networkAreas[i].AreaId)
if err != nil {
return fmt.Errorf("destroying network area %s during CheckDestroy: %w", *networkAreas[i].AreaId, err)
}
}
}
return nil
}