Skip to content

Commit

Permalink
Add terraform resource and data source for infrastructure access endp…
Browse files Browse the repository at this point in the history
…oints
  • Loading branch information
SaiDadireddy committed Sep 19, 2024
1 parent e17b3e1 commit 507c22a
Show file tree
Hide file tree
Showing 7 changed files with 581 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .changelog/4062.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```release-note:enhancement
provider: add new data source and resource for infrastructure target
```

```release-note:enhancement
resource/cloudflare_zero_trust_infrastructure_target: add new resource infrastructure target
```

```release-note:enhancement
data_source/cloudflare_zero_trust_infrastructure_targets: add new data source to read infrastructure targets
```
105 changes: 105 additions & 0 deletions internal/sdkv2provider/data_source_infrastructure_targets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package sdkv2provider

import (
"context"
"fmt"

"github.com/cloudflare/cloudflare-go"
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceCloudflareZeroTrustInfrastructureTargets() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
consts.AccountIDSchemaKey: {
Description: consts.AccountIDSchemaDescription,
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"hostname": {
Type: schema.TypeString,
Optional: true,
Description: "The hostname of a target",
},
"hostname_contains": {
Type: schema.TypeString,
Optional: true,
Description: "A partial match to the hostname of a target.",
},
"ip_v4": {
Type: schema.TypeString,
Optional: true,
Description: "The IPv4 address of the target.",
},
"ip_v6": {
Type: schema.TypeString,
Optional: true,
Description: "The IPv6 address of the target",
},
"virtual_network_id": {
Type: schema.TypeString,
Optional: true,
Description: "The private virtual network identifier of the target.",
},
"created_after": {
Type: schema.TypeString,
Optional: true,
Description: "The date and time at which the target was created.",
},
"modified_after": {
Type: schema.TypeString,
Optional: true,
Description: "The date and time at which the target was modified.",
},
},
Description: "Use this datasource to lookup a tunnel in an account.",
ReadContext: dataSourceCloudflareInfrastructureTargetRead,
}
}

func dataSourceCloudflareInfrastructureTargetRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
tflog.Debug(ctx, "Reading Targets")
client := meta.(*cloudflare.API)
accID := d.Get(consts.AccountIDSchemaKey).(string)

hostname := d.Get("hostname").(string)
hostnameContains := d.Get("hostname_contains").(string)
ipv4 := d.Get("ip_v4").(string)
ipv6 := d.Get("ip_v6").(string)
vnetId := d.Get("virtual_network_id").(string)
createdAfter := d.Get("created_after").(string)
modifiedAfter := d.Get("created_after").(string)
checkSetNil := func(s string) *string {
if s == "" {
return nil
} else {
return &s
}
}

params := cloudflare.TargetListParams{
CreatedAfter: *checkSetNil(createdAfter),
Hostname: *checkSetNil(hostname),
HostnameContains: *checkSetNil(hostnameContains),
IPV4: *checkSetNil(ipv4),
IPV6: *checkSetNil(ipv6),
ModifedAfter: *checkSetNil(modifiedAfter),
VirtualNetworkId: *checkSetNil(vnetId),
}

targets, _, err := client.ListInfrastructureTargets(ctx, cloudflare.AccountIdentifier(accID), params)
if err != nil {
return diag.FromErr(fmt.Errorf("failed to fetch Infrastructure Targets: %w", err))
}
if len(targets) == 0 {
return diag.FromErr(fmt.Errorf("no Infrastructure Targets matching given query parameters"))
}
if err = d.Set("targets", targets); err != nil {
return diag.FromErr(fmt.Errorf("error setting Infrastructure Targets set: %w", err))
}
return nil
}
114 changes: 114 additions & 0 deletions internal/sdkv2provider/data_source_infrastructure_targets_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package sdkv2provider

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestAccCloudflareTarget_MatchHostname(t *testing.T) {
rnd1 := generateRandomResourceName()
rnd2 := generateRandomResourceName()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testCloudflareInfrastructureTargetsMatchNoIpv6(rnd1),
Check: resource.ComposeTestCheckFunc(
// We should expect this data source to have 1 resource
resource.TestCheckResourceAttr("data.cloudflare_zero_trust_infrastructure_targets."+rnd1, "resources.#", "1"),
// Check that there is no ipv6 object in this resource
resource.TestCheckNoResourceAttr("data.cloudflare_zero_trust_infrastructure_targets."+rnd1, "ip.ipv6"),
// Check the existing attributes of this resource
resource.TestCheckTypeSetElemNestedAttrs("data.cloudflare_zero_trust_infrastructure_targets."+rnd1, "resources.*", map[string]string{
"hostname": rnd1,
"ip.ipv4.ip_addr": "187.26.29.249",
"ip.ipv4.virtual_network_id": "c77b744e-acc8-428f-9257-6878c046ed55",
}),
),
},
{
Config: testCloudflareInfrastructureTargetsMatchAll(rnd1, rnd2),
Check: resource.ComposeTestCheckFunc(
// Expect this data source to have 2 resources
resource.TestCheckResourceAttr("data.cloudflare_zero_trust_infrastructure_targets.all", "resources.#", "2"),
// Check the attributes of the first resource
resource.TestCheckTypeSetElemNestedAttrs("data.cloudflare_zero_trust_infrastructure_targets.all", "resources.*", map[string]string{
"hostname": rnd1,
"ip.ipv4.ip_addr": "187.26.29.249",
"ip.ipv4.virtual_network_id": "c77b744e-acc8-428f-9257-6878c046ed55",
}),
// Check the attributes of the second resource
resource.TestCheckTypeSetElemNestedAttrs("data.cloudflare_zero_trust_infrastructure_targets.all", "resources.*", map[string]string{
"hostname": rnd2,
"ip.ipv4.ip_addr": "250.26.29.250",
"ip.ipv6.ip_addr": "64c0:64e8:f0b4:8dbf:7104:72b0:ec8f:f5e0",
"ip.ipv6.virtual_network_id": "01920a8c-dc14-7bb2-b67b-14c858494a54",
}),
),
},
},
})
}

func testCloudflareInfrastructureTargetsMatchNoIpv6(hostname string) string {
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
return fmt.Sprintf(`
resource "cloudflare_zero_trust_infrastructure_target" "%[2]s" {
account_id = "%[1]s"
hostname = "%[2]s"
ip = {
ipv4 = {
ip_addr = "187.26.29.249",
virtual_network_id = "c77b744e-acc8-428f-9257-6878c046ed55"
}
}
}
data "cloudflare_zero_trust_infrastructure_targets" "%[2]s" {
depends_on = [cloudflare_zero_trust_infrastructure_target.%[2]s]
}
`, accountID, hostname)
}

func testCloudflareInfrastructureTargetsMatchAll(hostname1 string, hostname2 string) string {
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
return fmt.Sprintf(`
resource "cloudflare_zero_trust_infrastructure_target" "%[2]s" {
account_id = "%[1]s"
hostname = "%[2]s"
ip = {
ipv4 = {
ip_addr = "187.26.29.249",
virtual_network_id = "c77b744e-acc8-428f-9257-6878c046ed55"
}
}
}
resource "cloudflare_zero_trust_infrastructure_target" "%[3]s" {
account_id = "%[1]s"
hostname = "%[3]s"
ip = {
ipv4 = {
ip_addr = "250.26.29.250",
virtual_network_id = "01920a8c-dc14-7bb2-b67b-14c858494a54"
},
ipv6 = {
ip_addr = "64c0:64e8:f0b4:8dbf:7104:72b0:ec8f:f5e0",
virtual_network_id = "01920a8c-dc14-7bb2-b67b-14c858494a54"
}
}
}
data "cloudflare_zero_trust_infrastructure_targets" "all" {
depends_on = [
cloudflare_zero_trust_infrastructure_target.%[2]s,
cloudflare_zero_trust_infrastructure_target.%[3]s
]
}
`, accountID, hostname1, hostname2)
}
2 changes: 2 additions & 0 deletions internal/sdkv2provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ func New(version string) func() *schema.Provider {
"cloudflare_accounts": dataSourceCloudflareAccounts(),
"cloudflare_devices": dataSourceCloudflareDevices(),
"cloudflare_device_posture_rules": dataSourceCloudflareDevicePostureRules(),
"cloudflare_zero_trust_infrastructure_targets": dataSourceCloudflareZeroTrustInfrastructureTargets(),
"cloudflare_ip_ranges": dataSourceCloudflareIPRanges(),
"cloudflare_list": dataSourceCloudflareList(),
"cloudflare_lists": dataSourceCloudflareLists(),
Expand Down Expand Up @@ -258,6 +259,7 @@ func New(version string) func() *schema.Provider {
"cloudflare_healthcheck": resourceCloudflareHealthcheck(),
"cloudflare_hostname_tls_setting": resourceCloudflareHostnameTLSSetting(),
"cloudflare_hostname_tls_setting_ciphers": resourceCloudflareHostnameTLSSettingCiphers(),
"cloudflare_zero_trust_infrastructure_target": resourceCloudflareZeroTrustInfrastructureTarget(),
"cloudflare_ipsec_tunnel": resourceCloudflareIPsecTunnel(),
"cloudflare_magic_wan_ipsec_tunnel": resourceCloudflareMagicWANIPsecTunnel(),
"cloudflare_keyless_certificate": resourceCloudflareKeylessCertificate(),
Expand Down
Loading

0 comments on commit 507c22a

Please sign in to comment.