diff --git a/.github/workflows/fabric_acctest.yml b/.github/workflows/fabric_acctest.yml index 102c39b3b..86ba9e6d7 100644 --- a/.github/workflows/fabric_acctest.yml +++ b/.github/workflows/fabric_acctest.yml @@ -129,7 +129,7 @@ jobs: SWEEP_DIR: "./equinix" run: | # Added sweep-run to filter Fabric PNFV test - go test ${SWEEP_DIR} -v -timeout 180m -sweep=${SWEEP} -sweep-allow-failures=${SWEEP_ALLOW_FAILURES} -sweep-run=$(grep -o 'AddTestSweepers("[^"]*PNFV"' equinix/resource_fabric_* | cut -d '"' -f2 | paste -s -d, -) + go test $(go list ./... | grep 'internal/sweep\|equinix/equinix') -v -timeout 180m -sweep=${SWEEP} -sweep-allow-failures=${SWEEP_ALLOW_FAILURES} -sweep-run=$(grep -or 'AddTestSweepers("[^"]*"' | grep "_fabric_" | cut -d '"' -f2 | paste -s -d, -) - name: Upload coverage to Codecov if: ${{ always() }} @@ -194,10 +194,9 @@ jobs: METAL_AUTH_TOKEN: ${{ secrets.METAL_AUTH_TOKEN }} SWEEP: "all" #Flag required to define the regions that the sweeper is to be ran in SWEEP_ALLOW_FAILURES: "true" #Enable to allow Sweeper Tests to continue after failures - SWEEP_DIR: "./equinix" run: | # Added sweep-run to filter Fabric PFCR test - go test ${SWEEP_DIR} -v -timeout 180m -sweep=${SWEEP} -sweep-allow-failures=${SWEEP_ALLOW_FAILURES} -sweep-run=$(grep -o 'AddTestSweepers("[^"]*PFCR"' equinix/resource_fabric_* | cut -d '"' -f2 | paste -s -d, -) + go test $(go list ./... | grep 'internal/sweep\|equinix/equinix') -v -timeout 180m -sweep=${SWEEP} -sweep-allow-failures=${SWEEP_ALLOW_FAILURES} -sweep-run=$(grep -or 'AddTestSweepers("[^"]*"' | grep "_fabric_" | cut -d '"' -f2 | paste -s -d, -) - name: Upload coverage to Codecov if: ${{ always() }} diff --git a/internal/config/config.go b/internal/config/config.go index 89ffcf001..d4d8dd6c6 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -149,6 +149,16 @@ func (c *Config) NewFabricClientForSDK(d *schema.ResourceData) *fabricv4.APIClie return client } +// Shim for Fabric tests. +// Deprecated: when the acceptance package starts to contain API clients for testing/cleanup this will move with them +func (c *Config) NewFabricClientForTesting() *fabricv4.APIClient { + client := c.newFabricClient() + + client.GetConfig().UserAgent = fmt.Sprintf("tf-acceptance-tests %v", client.GetConfig().UserAgent) + + return client +} + // newFabricClient returns the base fabricv4 client that is then used for either the sdkv2 or framework // implementations of the Terraform Provider with exported Methods func (c *Config) newFabricClient() *fabricv4.APIClient { diff --git a/internal/resources/fabric/connection/resource_test.go b/internal/resources/fabric/connection/resource_test.go index cc19138e4..f728fa2ee 100644 --- a/internal/resources/fabric/connection/resource_test.go +++ b/internal/resources/fabric/connection/resource_test.go @@ -14,17 +14,6 @@ import ( "github.com/hashicorp/terraform-plugin-testing/terraform" ) -func init() { - resource.AddTestSweepers("equinix_fabric_connection_PNFV", &resource.Sweeper{ - Name: "equinix_fabric_connection", - F: testSweepConnections, - }) -} - -func testSweepConnections(region string) error { - return nil -} - func TestAccFabricCreatePort2SPConnection_PPDS(t *testing.T) { ports := testing_helpers.GetFabricEnvPorts(t) connectionsTestData := testing_helpers.GetFabricEnvConnectionTestData(t) diff --git a/internal/resources/fabric/connection/sweeper.go b/internal/resources/fabric/connection/sweeper.go new file mode 100644 index 000000000..90ea8aec0 --- /dev/null +++ b/internal/resources/fabric/connection/sweeper.go @@ -0,0 +1,74 @@ +package connection + +import ( + "context" + "errors" + "fmt" + "github.com/equinix/equinix-sdk-go/services/fabricv4" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/sweep" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "log" +) + +func AddTestSweeper() { + resource.AddTestSweepers("equinix_fabric_connection", &resource.Sweeper{ + Name: "equinix_fabric_connection", + Dependencies: []string{}, + F: testSweepConnections, + }) +} + +func testSweepConnections(region string) error { + var errs []error + log.Printf("[DEBUG] Sweeping Fabric Connections") + ctx := context.Background() + meta, err := sweep.GetConfigForFabric() + if err != nil { + return fmt.Errorf("error getting configuration for sweeping Conections: %s", err) + } + meta.Load(ctx) + fabric := meta.NewFabricClientForTesting() + + name := fabricv4.SEARCHFIELDNAME_NAME + equinixStatus := fabricv4.SEARCHFIELDNAME_OPERATION_EQUINIX_STATUS + likeOperator := fabricv4.EXPRESSIONOPERATOR_LIKE + equalOperator := fabricv4.EXPRESSIONOPERATOR_EQUAL + limit := int32(100) + connectionsSearchRequest := fabricv4.SearchRequest{ + Filter: &fabricv4.Expression{ + And: []fabricv4.Expression{ + { + Property: &name, + Operator: &likeOperator, + Values: sweep.FabricTestResourceSuffixes, + }, + { + Property: &equinixStatus, + Operator: &equalOperator, + Values: []string{string(fabricv4.EQUINIXSTATUS_PROVISIONED)}, + }, + }, + }, + Pagination: &fabricv4.PaginationRequest{ + Limit: &limit, + }, + } + + fabricConnections, _, err := fabric.ConnectionsApi.SearchConnections(ctx).SearchRequest(connectionsSearchRequest).Execute() + if err != nil { + return fmt.Errorf("error getting connections list for sweeping fabric connections: %s", err) + } + + for _, connection := range fabricConnections.Data { + if sweep.IsSweepableFabricTestResource(connection.GetName()) { + log.Printf("[DEBUG] Deleting Connection: %s", connection.GetName()) + _, resp, err := fabric.ConnectionsApi.DeleteConnectionByUuid(ctx, connection.GetUuid()).Execute() + if equinix_errors.IgnoreHttpResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + errs = append(errs, fmt.Errorf("error deleting fabric connection: %s", err)) + } + } + } + + return errors.Join(errs...) +} diff --git a/internal/sweep/sweep.go b/internal/sweep/sweep.go index 981295ab7..11a98d699 100644 --- a/internal/sweep/sweep.go +++ b/internal/sweep/sweep.go @@ -12,20 +12,57 @@ import ( const ( // duplicated from equinix_sweeoer_test.go - testResourcePrefix = "tfacc" - missingMetalToken = "to run sweepers of Equinix Metal Resources, you must set %s" + testResourcePrefix = "tfacc" + cannotConvertTimeoutToInt = "cannot convert value of '%s' env variable to int" + missingFabricSecrets = "missing fabric clientId - %s, and clientSecret - %s" + missingMetalToken = "to run sweepers of Equinix Metal Resources, you must set %s" +) + +var ( + FabricTestResourceSuffixes = []string{"_PFCR", "_PNFV", "_PPDS"} ) func IsSweepableTestResource(namePrefix string) bool { return strings.HasPrefix(namePrefix, testResourcePrefix) } +func IsSweepableFabricTestResource(resourceName string) bool { + for _, suffix := range FabricTestResourceSuffixes { + if strings.HasSuffix(resourceName, suffix) { + return true + } + } + return false +} + +func GetConfigForFabric() (*config.Config, error) { + endpoint := env.GetWithDefault(config.EndpointEnvVar, config.DefaultBaseURL) + clientId := env.GetWithDefault(config.ClientIDEnvVar, "") + clientSecret := env.GetWithDefault(config.ClientSecretEnvVar, "") + if clientId == "" || clientSecret == "" { + return nil, fmt.Errorf(missingFabricSecrets, config.ClientIDEnvVar, config.ClientSecretEnvVar) + } + + clientTimeout := env.GetWithDefault(config.ClientTimeoutEnvVar, strconv.Itoa(config.DefaultTimeout)) + clientTimeoutInt, err := strconv.Atoi(clientTimeout) + if err != nil { + return nil, fmt.Errorf(cannotConvertTimeoutToInt, config.ClientTimeoutEnvVar) + } + + return &config.Config{ + BaseURL: endpoint, + ClientID: clientId, + ClientSecret: clientSecret, + RequestTimeout: time.Duration(clientTimeoutInt) * time.Second, + }, nil +} + func GetConfigForMetal() (*config.Config, error) { endpoint := env.GetWithDefault(config.EndpointEnvVar, config.DefaultBaseURL) clientTimeout := env.GetWithDefault(config.ClientTimeoutEnvVar, strconv.Itoa(config.DefaultTimeout)) clientTimeoutInt, err := strconv.Atoi(clientTimeout) if err != nil { - return nil, fmt.Errorf("cannot convert value of '%s' env variable to int", config.ClientTimeoutEnvVar) + return nil, fmt.Errorf(cannotConvertTimeoutToInt, config.ClientTimeoutEnvVar) } metalAuthToken := env.GetWithDefault(config.MetalAuthTokenEnvVar, "") diff --git a/internal/sweep/sweep_test.go b/internal/sweep/sweep_test.go index 8a725898f..3b1ad7780 100644 --- a/internal/sweep/sweep_test.go +++ b/internal/sweep/sweep_test.go @@ -1,9 +1,9 @@ package sweep_test import ( - "github.com/equinix/terraform-provider-equinix/internal/resources/metal/vlan" "testing" + fabric_connection "github.com/equinix/terraform-provider-equinix/internal/resources/fabric/connection" "github.com/equinix/terraform-provider-equinix/internal/resources/metal/connection" "github.com/equinix/terraform-provider-equinix/internal/resources/metal/device" "github.com/equinix/terraform-provider-equinix/internal/resources/metal/organization" @@ -11,7 +11,9 @@ import ( "github.com/equinix/terraform-provider-equinix/internal/resources/metal/ssh_key" "github.com/equinix/terraform-provider-equinix/internal/resources/metal/user_api_key" "github.com/equinix/terraform-provider-equinix/internal/resources/metal/virtual_circuit" + "github.com/equinix/terraform-provider-equinix/internal/resources/metal/vlan" "github.com/equinix/terraform-provider-equinix/internal/resources/metal/vrf" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -25,6 +27,7 @@ func TestMain(m *testing.M) { func addTestSweepers() { connection.AddTestSweeper() device.AddTestSweeper() + fabric_connection.AddTestSweeper() organization.AddTestSweeper() project.AddTestSweeper() ssh_key.AddTestSweeper()