Files

223 lines
6.5 KiB
Go

// Copyright IBM Corp. 2020, 2026
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"fmt"
"net/http"
"testing"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/targets"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/stretchr/testify/require"
)
const fooTargetHostSourceTemplate = `
resource "boundary_host_catalog" "foo" {
type = "static"
name = "test"
description = "test catalog"
scope_id = boundary_scope.proj1.id
depends_on = [boundary_role.proj1_admin]
}
resource "boundary_host" "foo" {
name = "foo"
host_catalog_id = boundary_host_catalog.foo.id
type = "static"
address = "10.0.0.1"
}
resource "boundary_host_set" "foo" {
name = "foo"
type = "static"
host_catalog_id = boundary_host_catalog.foo.id
host_ids = [
boundary_host.foo.id,
]
}
resource "boundary_target" "foo" {
name = "test-target"
type = "tcp"
scope_id = boundary_scope.proj1.id
default_port = 22
default_client_port = 1022
depends_on = [boundary_role.proj1_admin]
lifecycle {
ignore_changes = [host_source_ids]
}
}
%s
`
const fooTargetHostSourceResource = `resource "boundary_target_host_source" "foo" {
target_id = boundary_target.foo.id
host_source_id = boundary_host_set.foo.id
}
`
var (
fooTargetHostSourceAttachment = fmt.Sprintf(fooTargetHostSourceTemplate, fooTargetHostSourceResource)
fooTargetHostSourceDetached = fmt.Sprintf(fooTargetHostSourceTemplate, "")
)
func TestAccTargetHostSource(t *testing.T) {
cfg, err := loadTestConfig()
require.NoError(t, err)
suffix := id.UniqueId()
url := cfg.BoundaryAddr
var provider *schema.Provider
resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProviderFactories: providerFactories(&provider),
CheckDestroy: testAccCheckTargetHostSourceDestroy(t, provider),
Steps: []resource.TestStep{
{
Config: testConfig(url, fooOrg(suffix), firstProjectFoo, fooTargetHostSourceAttachment),
Check: resource.ComposeTestCheckFunc(
testAccCheckTargetHostSourceExists(provider, "boundary_target_host_source.foo"),
resource.TestCheckResourceAttrSet("boundary_target_host_source.foo", targetHostSourceTargetIdKey),
resource.TestCheckResourceAttrSet("boundary_target_host_source.foo", targetHostSourceIdKey),
testAccCheckTargetHostSourceAttached(provider, "boundary_target.foo", "boundary_host_set.foo"),
),
},
importStep("boundary_target_host_source.foo"),
{
Config: testConfig(url, fooOrg(suffix), firstProjectFoo, fooTargetHostSourceDetached),
Check: resource.ComposeTestCheckFunc(
testAccCheckTargetResourceHostSource(provider, "boundary_target.foo", nil),
),
},
},
})
}
func testAccCheckTargetHostSourceExists(testProvider *schema.Provider, name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("target host source resource not found: %s", name)
}
if rs.Primary.ID == "" {
return fmt.Errorf("target host source resource ID is not set")
}
targetID := rs.Primary.Attributes[targetHostSourceTargetIdKey]
hostSourceID := rs.Primary.Attributes[targetHostSourceIdKey]
if targetID == "" {
return fmt.Errorf("target_id is not set")
}
if hostSourceID == "" {
return fmt.Errorf("host_source_id is not set")
}
md := testProvider.Meta().(*metaData)
targetClient := targets.NewClient(md.client)
targetResource, err := targetClient.Read(context.Background(), targetID)
if err != nil {
return fmt.Errorf("error reading target %q: %v", targetID, err)
}
if targetResource == nil {
return fmt.Errorf("target %q nil after read", targetID)
}
for _, id := range targetResource.Item.HostSourceIds {
if id == hostSourceID {
return nil
}
}
return fmt.Errorf("host source %q not attached to target %q", hostSourceID, targetID)
}
}
func testAccCheckTargetHostSourceAttached(testProvider *schema.Provider, targetName, hostSourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
targetResource, ok := s.RootModule().Resources[targetName]
if !ok {
return fmt.Errorf("target resource not found: %s", targetName)
}
hostSourceResource, ok := s.RootModule().Resources[hostSourceName]
if !ok {
return fmt.Errorf("host source resource not found: %s", hostSourceName)
}
targetID := targetResource.Primary.ID
hostSourceID := hostSourceResource.Primary.ID
if targetID == "" {
return fmt.Errorf("target resource ID is not set")
}
if hostSourceID == "" {
return fmt.Errorf("host source resource ID is not set")
}
md := testProvider.Meta().(*metaData)
targetClient := targets.NewClient(md.client)
targetResourceState, err := targetClient.Read(context.Background(), targetID)
if err != nil {
return fmt.Errorf("error reading target %q: %v", targetID, err)
}
if targetResourceState == nil {
return fmt.Errorf("target %q nil after read", targetID)
}
for _, id := range targetResourceState.Item.HostSourceIds {
if id == hostSourceID {
return nil
}
}
return fmt.Errorf("host source %q not attached to target %q", hostSourceID, targetID)
}
}
func testAccCheckTargetHostSourceDestroy(t *testing.T, testProvider *schema.Provider) resource.TestCheckFunc {
return func(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "boundary_target_host_source" {
continue
}
targetID := rs.Primary.Attributes[targetHostSourceTargetIdKey]
hostSourceID := rs.Primary.Attributes[targetHostSourceIdKey]
if targetID == "" || hostSourceID == "" {
continue
}
md := testProvider.Meta().(*metaData)
targetClient := targets.NewClient(md.client)
targetResource, err := targetClient.Read(context.Background(), targetID)
if err != nil {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound {
continue
}
return fmt.Errorf("error reading target %q while checking destroy: %v", targetID, err)
}
if targetResource == nil {
continue
}
for _, id := range targetResource.Item.HostSourceIds {
if id == hostSourceID {
return fmt.Errorf("host source %q still attached to target %q after destroy", hostSourceID, targetID)
}
}
}
return nil
}
}