-
Notifications
You must be signed in to change notification settings - Fork 630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add terraform resource and data source for Infrastructure Access Target #4077
Merged
jacobbednarz
merged 22 commits into
cloudflare:master
from
SaiDadireddy:sdadireddy/infrastructure-access
Sep 26, 2024
Merged
Changes from 16 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
17323b7
Add terraform resource and data source for infrastructure access endp…
SaiDadireddy 33d19a1
Create new schema, resource, and data source in internal/framework as…
SaiDadireddy 8fb8901
Make created_at and modified_at resource attributes read-only
SaiDadireddy 24c43c0
Fix read only
SaiDadireddy 4d3e1c0
Add models for nested objects and add type conversions between basety…
SaiDadireddy 379684b
Add IP as an attribute instead of a block to control required/optional
SaiDadireddy 608edf0
Fix IP related issues and restructure
SaiDadireddy e5fb550
Resource fixes from testing
SaiDadireddy 2fb2d38
Data source fixup
SaiDadireddy 50fbd00
Remove local override for cloudflare-go
SaiDadireddy 7dc42af
fix name
SaiDadireddy 0a7c223
Update test cases
SaiDadireddy 8b97c80
Merge branch 'master' into sdadireddy/infrastructure-access
jacobbednarz 598e3bf
fix lint
jacobbednarz 8f54346
Update 4062.txt
jacobbednarz debfd55
fix assertions
jacobbednarz d765a81
fix tests
jacobbednarz a90fefc
rename test to match conventions
jacobbednarz 19dc76e
Fix tests
SaiDadireddy 127bb45
re-fix tests
jacobbednarz 4eb825d
`make docs`
jacobbednarz 94a8bef
Rename 4062.txt to 4077.txt
jacobbednarz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
```release-note:new-datasource | ||
cloudflare_infrastructure_access_targets | ||
``` | ||
|
||
```release-note:new-resource | ||
cloudflare_infrastructure_access_target | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
internal/framework/service/infrastructure_access_target/data_source.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package infrastructure_access_target | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/cloudflare/cloudflare-go" | ||
"github.com/cloudflare/terraform-provider-cloudflare/internal/framework/muxclient" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
var _ datasource.DataSource = &InfrastructureAccessTargetDataSource{} | ||
|
||
func NewDataSource() datasource.DataSource { | ||
return &InfrastructureAccessTargetDataSource{} | ||
} | ||
|
||
type InfrastructureAccessTargetDataSource struct { | ||
client *muxclient.Client | ||
} | ||
|
||
func (d *InfrastructureAccessTargetDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_infrastructure_access_targets" | ||
} | ||
|
||
func (d *InfrastructureAccessTargetDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
if req.ProviderData == nil { | ||
return | ||
} | ||
|
||
client, ok := req.ProviderData.(*muxclient.Client) | ||
if !ok { | ||
resp.Diagnostics.AddError( | ||
"Unexpected resource configure type", | ||
fmt.Sprintf("Expected *muxclient.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), | ||
) | ||
return | ||
} | ||
|
||
d.client = client | ||
} | ||
|
||
func (d *InfrastructureAccessTargetDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var data *InfrastructureAccessTargetsModel | ||
|
||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
accountId := data.AccountID.ValueString() | ||
if accountId == "" { | ||
resp.Diagnostics.AddError("failed to update infrastructure access target", "account id cannot be an empty string") | ||
return | ||
} | ||
params := cloudflare.InfrastructureAccessTargetListParams{ | ||
Hostname: data.Hostname.ValueString(), | ||
HostnameContains: data.HostnameContains.ValueString(), | ||
IPV4: data.IPV4.ValueString(), | ||
IPV6: data.IPV6.ValueString(), | ||
CreatedAfter: data.CreatedAfter.ValueString(), | ||
ModifedAfter: data.ModifiedAfter.ValueString(), | ||
VirtualNetworkId: data.VirtualNetworkId.ValueString(), | ||
} | ||
|
||
allTargets, _, err := d.client.V1.ListInfrastructureAccessTargets(ctx, cloudflare.AccountIdentifier(accountId), params) | ||
if err != nil { | ||
resp.Diagnostics.AddError("failed to fetch Infrastructure Access Targets: %w", err.Error()) | ||
return | ||
} | ||
if len(allTargets) == 0 { | ||
resp.Diagnostics.AddError("failed to fetch Infrastructure Access Targets", "no Infrastructure Access Targets matching given query parameters") | ||
} | ||
|
||
var targets []InfrastructureAccessTargetModel | ||
for _, target := range allTargets { | ||
targets = append(targets, InfrastructureAccessTargetModel{ | ||
AccountID: types.StringValue(accountId), | ||
Hostname: types.StringValue(target.Hostname), | ||
ID: types.StringValue(target.ID), | ||
IP: convertIPInfoToBaseTypeObject(target.IP), | ||
CreatedAt: types.StringValue(target.CreatedAt), | ||
ModifiedAt: types.StringValue(target.ModifiedAt), | ||
}) | ||
} | ||
|
||
data.Targets = targets | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) | ||
} |
115 changes: 115 additions & 0 deletions
115
internal/framework/service/infrastructure_access_target/data_source_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package infrastructure_access_target_test | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
|
||
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest" | ||
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils" | ||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
) | ||
|
||
func TestAccCloudflareInfraAccessTarget_DataSource(t *testing.T) { | ||
rnd1 := utils.GenerateRandomResourceName() | ||
rnd2 := utils.GenerateRandomResourceName() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { acctest.TestAccPreCheck(t) }, | ||
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testCloudflareInfrastructureTargetsMatchNoIpv6(rnd1), | ||
Check: resource.ComposeTestCheckFunc( | ||
// We should expect this data source to have 1 resource. | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets."+rnd1, "targets.#", "1"), | ||
// Check that there is no ipv6 object in this resource. | ||
resource.TestCheckNoResourceAttr("data.cloudflare_infrastructure_access_targets."+rnd1, "ip.ipv6"), | ||
// Check the existing attributes of this resource. | ||
resource.TestCheckResourceAttr("cloudflare_infrastructure_access_target."+rnd1, "hostname", rnd1), | ||
resource.TestCheckResourceAttr("cloudflare_infrastructure_access_target."+rnd1, "hostname", rnd1), | ||
resource.TestCheckResourceAttr("cloudflare_infrastructure_access_target."+rnd1, "ip.ipv4.ip_addr", "187.26.29.233"), | ||
resource.TestCheckResourceAttr("cloudflare_infrastructure_access_target."+rnd1, "ip.ipv4.virtual_network_id", "b9c90134-52de-4903-81e8-004a3a06b435"), | ||
), | ||
}, | ||
{ | ||
Config: testCloudflareInfrastructureTargetsMatchAll(rnd1, rnd2), | ||
Check: resource.ComposeTestCheckFunc( | ||
// Expect this data source to have 2 resources. | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.#", "2"), | ||
// Check the attributes of the first resource. | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.0.hostname", rnd2), | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.0.ip.ipv4.ip_addr", "250.26.29.250"), | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.0.ip.ipv6.ip_addr", "64c0:64e8:f0b4:8dbf:7104:72b0:ec8f:f5e0"), | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.0.ip.ipv6.virtual_network_id", "b9c90134-52de-4903-81e8-004a3a06b435"), | ||
/// Check the attributes of the second resource. | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.1.hostname", rnd1), | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.1.ip.ipv4.ip_addr", "187.26.29.249"), | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.1.ip.ipv4.virtual_network_id", "b9c90134-52de-4903-81e8-004a3a06b435"), | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.1.ip.ipv6.ip_addr", "64c0:64e8:f0b4:8dbf:7104:72b0:ec8f:f5e0"), | ||
resource.TestCheckResourceAttr("data.cloudflare_infrastructure_access_targets.all", "targets.1.ip.ipv6.virtual_network_id", "b9c90134-52de-4903-81e8-004a3a06b435"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testCloudflareInfrastructureTargetsMatchNoIpv6(hostname string) string { | ||
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") | ||
return fmt.Sprintf(` | ||
resource "cloudflare_infrastructure_access_target" "%[2]s" { | ||
account_id = "%[1]s" | ||
hostname = "%[2]s" | ||
ip = { | ||
ipv4 = { | ||
ip_addr = "187.26.29.233", | ||
virtual_network_id = "b9c90134-52de-4903-81e8-004a3a06b435" | ||
} | ||
} | ||
} | ||
|
||
data "cloudflare_infrastructure_access_targets" "%[2]s" { | ||
depends_on = [cloudflare_infrastructure_access_target.%[2]s] | ||
account_id = "%[1]s" | ||
} | ||
`, accountID, hostname) | ||
} | ||
|
||
func testCloudflareInfrastructureTargetsMatchAll(hostname1 string, hostname2 string) string { | ||
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") | ||
return fmt.Sprintf(` | ||
resource "cloudflare_infrastructure_access_target" "%[2]s" { | ||
account_id = "%[1]s" | ||
hostname = "%[2]s" | ||
ip = { | ||
ipv4 = { | ||
ip_addr = "187.26.29.249", | ||
virtual_network_id = "b9c90134-52de-4903-81e8-004a3a06b435" | ||
} | ||
} | ||
} | ||
|
||
resource "cloudflare_infrastructure_access_target" "%[3]s" { | ||
account_id = "%[1]s" | ||
hostname = "%[3]s" | ||
ip = { | ||
ipv4 = { | ||
ip_addr = "250.26.29.250", | ||
virtual_network_id = "b9c90134-52de-4903-81e8-004a3a06b435" | ||
}, | ||
ipv6 = { | ||
ip_addr = "64c0:64e8:f0b4:8dbf:7104:72b0:ec8f:f5e0", | ||
virtual_network_id = "b9c90134-52de-4903-81e8-004a3a06b435" | ||
} | ||
} | ||
} | ||
|
||
data "cloudflare_infrastructure_access_targets" "all" { | ||
depends_on = [ | ||
cloudflare_infrastructure_access_target.%[2]s, | ||
cloudflare_infrastructure_access_target.%[3]s | ||
] | ||
account_id = "%[1]s" | ||
} | ||
`, accountID, hostname1, hostname2) | ||
} |
36 changes: 36 additions & 0 deletions
36
internal/framework/service/infrastructure_access_target/model.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package infrastructure_access_target | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
type InfrastructureAccessTargetModel struct { | ||
AccountID types.String `tfsdk:"account_id"` | ||
Hostname types.String `tfsdk:"hostname"` | ||
ID types.String `tfsdk:"id"` | ||
IP types.Object `tfsdk:"ip"` | ||
CreatedAt types.String `tfsdk:"created_at"` | ||
ModifiedAt types.String `tfsdk:"modified_at"` | ||
} | ||
|
||
type InfrastructureAccessTargetIPInfoModel struct { | ||
IPV4 types.Object `tfsdk:"ipv4"` | ||
IPV6 types.Object `tfsdk:"ipv6"` | ||
} | ||
|
||
type InfrastructureAccessTargetIPDetailsModel struct { | ||
IPAddr types.String `tfsdk:"ip_addr"` | ||
VirtualNetworkId types.String `tfsdk:"virtual_network_id"` | ||
} | ||
|
||
type InfrastructureAccessTargetsModel struct { | ||
AccountID types.String `tfsdk:"account_id"` | ||
Hostname types.String `tfsdk:"hostname"` | ||
HostnameContains types.String `tfsdk:"hostname_contains"` | ||
IPV4 types.String `tfsdk:"ipv4"` | ||
IPV6 types.String `tfsdk:"ipv6"` | ||
VirtualNetworkId types.String `tfsdk:"virtual_network_id"` | ||
CreatedAfter types.String `tfsdk:"created_after"` | ||
ModifiedAfter types.String `tfsdk:"modified_after"` | ||
Targets []InfrastructureAccessTargetModel `tfsdk:"targets"` | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after fixing this, i think this is a legit failure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested the second test manually and it's working as expected. Asserting in this case is tricky with multiple resources in the returned data source since there is no strict ordering. Removed the second test, it's not necessary.