Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 57d76e2

Browse files
committedMar 19, 2025·
feat(custom_pages): add resource (#5343)
1 parent 559850d commit 57d76e2

17 files changed

+762
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
data "cloudflare_custom_pages" "example_custom_pages" {
2+
identifier = "023e105f4ecef8ad9ca31a8372d0c353"
3+
account_id = "account_id"
4+
zone_id = "zone_id"
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
data "cloudflare_custom_pages_list" "example_custom_pages_list" {
2+
account_id = "account_id"
3+
zone_id = "zone_id"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
resource "cloudflare_custom_pages" "example_custom_pages" {
2+
identifier = "023e105f4ecef8ad9ca31a8372d0c353"
3+
state = "default"
4+
url = "http://www.example.com"
5+
zone_id = "zone_id"
6+
}

‎internal/provider.go

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import (
4949
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/content_scanning_expression"
5050
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/custom_hostname"
5151
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/custom_hostname_fallback_origin"
52+
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/custom_pages"
5253
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/custom_ssl"
5354
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/d1_database"
5455
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/dcv_delegation"
@@ -562,6 +563,7 @@ func (p *CloudflareProvider) Resources(ctx context.Context) []func() resource.Re
562563
leaked_credential_check.NewResource,
563564
leaked_credential_check_rule.NewResource,
564565
content_scanning_expression.NewResource,
566+
custom_pages.NewResource,
565567
}
566568
}
567569

@@ -873,6 +875,8 @@ func (p *CloudflareProvider) DataSources(ctx context.Context) []func() datasourc
873875
leaked_credential_check.NewLeakedCredentialCheckDataSource,
874876
leaked_credential_check_rule.NewLeakedCredentialCheckRulesDataSource,
875877
content_scanning_expression.NewContentScanningExpressionsDataSource,
878+
custom_pages.NewCustomPagesDataSource,
879+
custom_pages.NewCustomPagesListDataSource,
876880
}
877881
}
878882

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
"fmt"
8+
"io"
9+
"net/http"
10+
11+
"github.com/cloudflare/cloudflare-go/v4"
12+
"github.com/cloudflare/cloudflare-go/v4/option"
13+
"github.com/cloudflare/terraform-provider-cloudflare/internal/apijson"
14+
"github.com/cloudflare/terraform-provider-cloudflare/internal/logging"
15+
"github.com/hashicorp/terraform-plugin-framework/datasource"
16+
)
17+
18+
type CustomPagesDataSource struct {
19+
client *cloudflare.Client
20+
}
21+
22+
var _ datasource.DataSourceWithConfigure = (*CustomPagesDataSource)(nil)
23+
24+
func NewCustomPagesDataSource() datasource.DataSource {
25+
return &CustomPagesDataSource{}
26+
}
27+
28+
func (d *CustomPagesDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
29+
resp.TypeName = req.ProviderTypeName + "_custom_pages"
30+
}
31+
32+
func (d *CustomPagesDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
33+
if req.ProviderData == nil {
34+
return
35+
}
36+
37+
client, ok := req.ProviderData.(*cloudflare.Client)
38+
39+
if !ok {
40+
resp.Diagnostics.AddError(
41+
"unexpected resource configure type",
42+
fmt.Sprintf("Expected *cloudflare.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
43+
)
44+
45+
return
46+
}
47+
48+
d.client = client
49+
}
50+
51+
func (d *CustomPagesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
52+
var data *CustomPagesDataSourceModel
53+
54+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
55+
56+
if resp.Diagnostics.HasError() {
57+
return
58+
}
59+
60+
params, diags := data.toReadParams(ctx)
61+
resp.Diagnostics.Append(diags...)
62+
if resp.Diagnostics.HasError() {
63+
return
64+
}
65+
66+
res := new(http.Response)
67+
env := CustomPagesResultDataSourceEnvelope{*data}
68+
_, err := d.client.CustomPages.Get(
69+
ctx,
70+
data.Identifier.ValueString(),
71+
params,
72+
option.WithResponseBodyInto(&res),
73+
option.WithMiddleware(logging.Middleware(ctx)),
74+
)
75+
if err != nil {
76+
resp.Diagnostics.AddError("failed to make http request", err.Error())
77+
return
78+
}
79+
bytes, _ := io.ReadAll(res.Body)
80+
err = apijson.UnmarshalComputed(bytes, &env)
81+
if err != nil {
82+
resp.Diagnostics.AddError("failed to deserialize http request", err.Error())
83+
return
84+
}
85+
data = &env.Result
86+
87+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
88+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
8+
"github.com/cloudflare/cloudflare-go/v4"
9+
"github.com/cloudflare/cloudflare-go/v4/custom_pages"
10+
"github.com/hashicorp/terraform-plugin-framework/diag"
11+
"github.com/hashicorp/terraform-plugin-framework/types"
12+
)
13+
14+
type CustomPagesResultDataSourceEnvelope struct {
15+
Result CustomPagesDataSourceModel `json:"result,computed"`
16+
}
17+
18+
type CustomPagesDataSourceModel struct {
19+
Identifier types.String `tfsdk:"identifier" path:"identifier,required"`
20+
AccountID types.String `tfsdk:"account_id" path:"account_id,optional"`
21+
ZoneID types.String `tfsdk:"zone_id" path:"zone_id,optional"`
22+
}
23+
24+
func (m *CustomPagesDataSourceModel) toReadParams(_ context.Context) (params custom_pages.CustomPageGetParams, diags diag.Diagnostics) {
25+
params = custom_pages.CustomPageGetParams{}
26+
27+
if !m.AccountID.IsNull() {
28+
params.AccountID = cloudflare.F(m.AccountID.ValueString())
29+
} else {
30+
params.ZoneID = cloudflare.F(m.ZoneID.ValueString())
31+
}
32+
33+
return
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
8+
"github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator"
9+
"github.com/hashicorp/terraform-plugin-framework/datasource"
10+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
11+
"github.com/hashicorp/terraform-plugin-framework/path"
12+
)
13+
14+
var _ datasource.DataSourceWithConfigValidators = (*CustomPagesDataSource)(nil)
15+
16+
func DataSourceSchema(ctx context.Context) schema.Schema {
17+
return schema.Schema{
18+
Attributes: map[string]schema.Attribute{
19+
"identifier": schema.StringAttribute{
20+
Description: "Identifier",
21+
Required: true,
22+
},
23+
"account_id": schema.StringAttribute{
24+
Description: "The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.",
25+
Optional: true,
26+
},
27+
"zone_id": schema.StringAttribute{
28+
Description: "The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.",
29+
Optional: true,
30+
},
31+
},
32+
}
33+
}
34+
35+
func (d *CustomPagesDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
36+
resp.Schema = DataSourceSchema(ctx)
37+
}
38+
39+
func (d *CustomPagesDataSource) ConfigValidators(_ context.Context) []datasource.ConfigValidator {
40+
return []datasource.ConfigValidator{
41+
datasourcevalidator.Conflicting(path.MatchRoot("account_id"), path.MatchRoot("zone_id")),
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages_test
4+
5+
import (
6+
"context"
7+
"testing"
8+
9+
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/custom_pages"
10+
"github.com/cloudflare/terraform-provider-cloudflare/internal/test_helpers"
11+
)
12+
13+
func TestCustomPagesDataSourceModelSchemaParity(t *testing.T) {
14+
t.Parallel()
15+
model := (*custom_pages.CustomPagesDataSourceModel)(nil)
16+
schema := custom_pages.DataSourceSchema(context.TODO())
17+
errs := test_helpers.ValidateDataSourceModelSchemaIntegrity(model, schema)
18+
errs.Report(t)
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
"fmt"
8+
9+
"github.com/cloudflare/cloudflare-go/v4"
10+
"github.com/cloudflare/terraform-provider-cloudflare/internal/apijson"
11+
"github.com/cloudflare/terraform-provider-cloudflare/internal/customfield"
12+
"github.com/hashicorp/terraform-plugin-framework/attr"
13+
"github.com/hashicorp/terraform-plugin-framework/datasource"
14+
)
15+
16+
type CustomPagesListDataSource struct {
17+
client *cloudflare.Client
18+
}
19+
20+
var _ datasource.DataSourceWithConfigure = (*CustomPagesListDataSource)(nil)
21+
22+
func NewCustomPagesListDataSource() datasource.DataSource {
23+
return &CustomPagesListDataSource{}
24+
}
25+
26+
func (d *CustomPagesListDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
27+
resp.TypeName = req.ProviderTypeName + "_custom_pages_list"
28+
}
29+
30+
func (d *CustomPagesListDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
31+
if req.ProviderData == nil {
32+
return
33+
}
34+
35+
client, ok := req.ProviderData.(*cloudflare.Client)
36+
37+
if !ok {
38+
resp.Diagnostics.AddError(
39+
"unexpected resource configure type",
40+
fmt.Sprintf("Expected *cloudflare.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
41+
)
42+
43+
return
44+
}
45+
46+
d.client = client
47+
}
48+
49+
func (d *CustomPagesListDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
50+
var data *CustomPagesListDataSourceModel
51+
52+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
53+
54+
if resp.Diagnostics.HasError() {
55+
return
56+
}
57+
58+
params, diags := data.toListParams(ctx)
59+
resp.Diagnostics.Append(diags...)
60+
if resp.Diagnostics.HasError() {
61+
return
62+
}
63+
64+
env := CustomPagesListResultListDataSourceEnvelope{}
65+
maxItems := int(data.MaxItems.ValueInt64())
66+
acc := []attr.Value{}
67+
if maxItems <= 0 {
68+
maxItems = 1000
69+
}
70+
page, err := d.client.CustomPages.List(ctx, params)
71+
if err != nil {
72+
resp.Diagnostics.AddError("failed to make http request", err.Error())
73+
return
74+
}
75+
76+
for page != nil && len(page.Result) > 0 {
77+
bytes := []byte(page.JSON.RawJSON())
78+
err = apijson.UnmarshalComputed(bytes, &env)
79+
if err != nil {
80+
resp.Diagnostics.AddError("failed to unmarshal http request", err.Error())
81+
return
82+
}
83+
acc = append(acc, env.Result.Elements()...)
84+
if len(acc) >= maxItems {
85+
break
86+
}
87+
page, err = page.GetNextPage()
88+
if err != nil {
89+
resp.Diagnostics.AddError("failed to fetch next page", err.Error())
90+
return
91+
}
92+
}
93+
94+
acc = acc[:min(len(acc), maxItems)]
95+
result, diags := customfield.NewObjectListFromAttributes[CustomPagesListResultDataSourceModel](ctx, acc)
96+
resp.Diagnostics.Append(diags...)
97+
data.Result = result
98+
99+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
8+
"github.com/cloudflare/cloudflare-go/v4"
9+
"github.com/cloudflare/cloudflare-go/v4/custom_pages"
10+
"github.com/cloudflare/terraform-provider-cloudflare/internal/customfield"
11+
"github.com/hashicorp/terraform-plugin-framework/diag"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
)
14+
15+
type CustomPagesListResultListDataSourceEnvelope struct {
16+
Result customfield.NestedObjectList[CustomPagesListResultDataSourceModel] `json:"result,computed"`
17+
}
18+
19+
type CustomPagesListDataSourceModel struct {
20+
AccountID types.String `tfsdk:"account_id" path:"account_id,optional"`
21+
ZoneID types.String `tfsdk:"zone_id" path:"zone_id,optional"`
22+
MaxItems types.Int64 `tfsdk:"max_items"`
23+
Result customfield.NestedObjectList[CustomPagesListResultDataSourceModel] `tfsdk:"result"`
24+
}
25+
26+
func (m *CustomPagesListDataSourceModel) toListParams(_ context.Context) (params custom_pages.CustomPageListParams, diags diag.Diagnostics) {
27+
params = custom_pages.CustomPageListParams{}
28+
29+
if !m.AccountID.IsNull() {
30+
params.AccountID = cloudflare.F(m.AccountID.ValueString())
31+
} else {
32+
params.ZoneID = cloudflare.F(m.ZoneID.ValueString())
33+
}
34+
35+
return
36+
}
37+
38+
type CustomPagesListResultDataSourceModel struct {
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
8+
"github.com/cloudflare/terraform-provider-cloudflare/internal/customfield"
9+
"github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator"
10+
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
11+
"github.com/hashicorp/terraform-plugin-framework/datasource"
12+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
13+
"github.com/hashicorp/terraform-plugin-framework/path"
14+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
15+
)
16+
17+
var _ datasource.DataSourceWithConfigValidators = (*CustomPagesListDataSource)(nil)
18+
19+
func ListDataSourceSchema(ctx context.Context) schema.Schema {
20+
return schema.Schema{
21+
Attributes: map[string]schema.Attribute{
22+
"account_id": schema.StringAttribute{
23+
Description: "The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.",
24+
Optional: true,
25+
},
26+
"zone_id": schema.StringAttribute{
27+
Description: "The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.",
28+
Optional: true,
29+
},
30+
"max_items": schema.Int64Attribute{
31+
Description: "Max items to fetch, default: 1000",
32+
Optional: true,
33+
Validators: []validator.Int64{
34+
int64validator.AtLeast(0),
35+
},
36+
},
37+
"result": schema.ListNestedAttribute{
38+
Description: "The items returned by the data source",
39+
Computed: true,
40+
CustomType: customfield.NewNestedObjectListType[CustomPagesListResultDataSourceModel](ctx),
41+
NestedObject: schema.NestedAttributeObject{
42+
Attributes: map[string]schema.Attribute{},
43+
},
44+
},
45+
},
46+
}
47+
}
48+
49+
func (d *CustomPagesListDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
50+
resp.Schema = ListDataSourceSchema(ctx)
51+
}
52+
53+
func (d *CustomPagesListDataSource) ConfigValidators(_ context.Context) []datasource.ConfigValidator {
54+
return []datasource.ConfigValidator{
55+
datasourcevalidator.ExactlyOneOf(path.MatchRoot("account_id"), path.MatchRoot("zone_id")),
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages_test
4+
5+
import (
6+
"context"
7+
"testing"
8+
9+
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/custom_pages"
10+
"github.com/cloudflare/terraform-provider-cloudflare/internal/test_helpers"
11+
)
12+
13+
func TestCustomPagesListDataSourceModelSchemaParity(t *testing.T) {
14+
t.Parallel()
15+
model := (*custom_pages.CustomPagesListDataSourceModel)(nil)
16+
schema := custom_pages.ListDataSourceSchema(context.TODO())
17+
errs := test_helpers.ValidateDataSourceModelSchemaIntegrity(model, schema)
18+
errs.Report(t)
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
8+
"github.com/hashicorp/terraform-plugin-framework/resource"
9+
)
10+
11+
var _ resource.ResourceWithUpgradeState = (*CustomPagesResource)(nil)
12+
13+
func (r *CustomPagesResource) UpgradeState(ctx context.Context) map[int64]resource.StateUpgrader {
14+
return map[int64]resource.StateUpgrader{}
15+
}
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"github.com/cloudflare/terraform-provider-cloudflare/internal/apijson"
7+
"github.com/hashicorp/terraform-plugin-framework/types"
8+
)
9+
10+
type CustomPagesResultEnvelope struct {
11+
Result CustomPagesModel `json:"result"`
12+
}
13+
14+
type CustomPagesModel struct {
15+
Identifier types.String `tfsdk:"identifier" path:"identifier,required"`
16+
AccountID types.String `tfsdk:"account_id" path:"account_id,optional"`
17+
ZoneID types.String `tfsdk:"zone_id" path:"zone_id,optional"`
18+
State types.String `tfsdk:"state" json:"state,required"`
19+
URL types.String `tfsdk:"url" json:"url,required"`
20+
}
21+
22+
func (m CustomPagesModel) MarshalJSON() (data []byte, err error) {
23+
return apijson.MarshalRoot(m)
24+
}
25+
26+
func (m CustomPagesModel) MarshalJSONForUpdate(state CustomPagesModel) (data []byte, err error) {
27+
return apijson.MarshalForUpdate(m, state)
28+
}
+223
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
"fmt"
8+
"io"
9+
"net/http"
10+
11+
"github.com/cloudflare/cloudflare-go/v4"
12+
"github.com/cloudflare/cloudflare-go/v4/custom_pages"
13+
"github.com/cloudflare/cloudflare-go/v4/option"
14+
"github.com/cloudflare/terraform-provider-cloudflare/internal/apijson"
15+
"github.com/cloudflare/terraform-provider-cloudflare/internal/logging"
16+
"github.com/hashicorp/terraform-plugin-framework/resource"
17+
)
18+
19+
// Ensure provider defined types fully satisfy framework interfaces.
20+
var _ resource.ResourceWithConfigure = (*CustomPagesResource)(nil)
21+
var _ resource.ResourceWithModifyPlan = (*CustomPagesResource)(nil)
22+
23+
func NewResource() resource.Resource {
24+
return &CustomPagesResource{}
25+
}
26+
27+
// CustomPagesResource defines the resource implementation.
28+
type CustomPagesResource struct {
29+
client *cloudflare.Client
30+
}
31+
32+
func (r *CustomPagesResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
33+
resp.TypeName = req.ProviderTypeName + "_custom_pages"
34+
}
35+
36+
func (r *CustomPagesResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
37+
if req.ProviderData == nil {
38+
return
39+
}
40+
41+
client, ok := req.ProviderData.(*cloudflare.Client)
42+
43+
if !ok {
44+
resp.Diagnostics.AddError(
45+
"unexpected resource configure type",
46+
fmt.Sprintf("Expected *cloudflare.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
47+
)
48+
49+
return
50+
}
51+
52+
r.client = client
53+
}
54+
55+
func (r *CustomPagesResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
56+
var data *CustomPagesModel
57+
58+
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
59+
60+
if resp.Diagnostics.HasError() {
61+
return
62+
}
63+
64+
dataBytes, err := data.MarshalJSON()
65+
if err != nil {
66+
resp.Diagnostics.AddError("failed to serialize http request", err.Error())
67+
return
68+
}
69+
res := new(http.Response)
70+
env := CustomPagesResultEnvelope{*data}
71+
params := custom_pages.CustomPageUpdateParams{}
72+
73+
if !data.AccountID.IsNull() {
74+
params.AccountID = cloudflare.F(data.AccountID.ValueString())
75+
} else {
76+
params.ZoneID = cloudflare.F(data.ZoneID.ValueString())
77+
}
78+
79+
_, err = r.client.CustomPages.Update(
80+
ctx,
81+
data.Identifier.ValueString(),
82+
params,
83+
option.WithRequestBody("application/json", dataBytes),
84+
option.WithResponseBodyInto(&res),
85+
option.WithMiddleware(logging.Middleware(ctx)),
86+
)
87+
if err != nil {
88+
resp.Diagnostics.AddError("failed to make http request", err.Error())
89+
return
90+
}
91+
bytes, _ := io.ReadAll(res.Body)
92+
err = apijson.UnmarshalComputed(bytes, &env)
93+
if err != nil {
94+
resp.Diagnostics.AddError("failed to deserialize http request", err.Error())
95+
return
96+
}
97+
data = &env.Result
98+
99+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
100+
}
101+
102+
func (r *CustomPagesResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
103+
var data *CustomPagesModel
104+
105+
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
106+
107+
if resp.Diagnostics.HasError() {
108+
return
109+
}
110+
111+
var state *CustomPagesModel
112+
113+
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
114+
115+
if resp.Diagnostics.HasError() {
116+
return
117+
}
118+
119+
dataBytes, err := data.MarshalJSONForUpdate(*state)
120+
if err != nil {
121+
resp.Diagnostics.AddError("failed to serialize http request", err.Error())
122+
return
123+
}
124+
res := new(http.Response)
125+
env := CustomPagesResultEnvelope{*data}
126+
params := custom_pages.CustomPageUpdateParams{}
127+
128+
if !data.AccountID.IsNull() {
129+
params.AccountID = cloudflare.F(data.AccountID.ValueString())
130+
} else {
131+
params.ZoneID = cloudflare.F(data.ZoneID.ValueString())
132+
}
133+
134+
_, err = r.client.CustomPages.Update(
135+
ctx,
136+
data.Identifier.ValueString(),
137+
params,
138+
option.WithRequestBody("application/json", dataBytes),
139+
option.WithResponseBodyInto(&res),
140+
option.WithMiddleware(logging.Middleware(ctx)),
141+
)
142+
if err != nil {
143+
resp.Diagnostics.AddError("failed to make http request", err.Error())
144+
return
145+
}
146+
bytes, _ := io.ReadAll(res.Body)
147+
err = apijson.UnmarshalComputed(bytes, &env)
148+
if err != nil {
149+
resp.Diagnostics.AddError("failed to deserialize http request", err.Error())
150+
return
151+
}
152+
data = &env.Result
153+
154+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
155+
}
156+
157+
func (r *CustomPagesResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
158+
var data *CustomPagesModel
159+
160+
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
161+
162+
if resp.Diagnostics.HasError() {
163+
return
164+
}
165+
166+
res := new(http.Response)
167+
env := CustomPagesResultEnvelope{*data}
168+
params := custom_pages.CustomPageGetParams{}
169+
170+
if !data.AccountID.IsNull() {
171+
params.AccountID = cloudflare.F(data.AccountID.ValueString())
172+
} else {
173+
params.ZoneID = cloudflare.F(data.ZoneID.ValueString())
174+
}
175+
176+
_, err := r.client.CustomPages.Get(
177+
ctx,
178+
data.Identifier.ValueString(),
179+
params,
180+
option.WithResponseBodyInto(&res),
181+
option.WithMiddleware(logging.Middleware(ctx)),
182+
)
183+
if res != nil && res.StatusCode == 404 {
184+
resp.Diagnostics.AddWarning("Resource not found", "The resource was not found on the server and will be removed from state.")
185+
resp.State.RemoveResource(ctx)
186+
return
187+
}
188+
if err != nil {
189+
resp.Diagnostics.AddError("failed to make http request", err.Error())
190+
return
191+
}
192+
bytes, _ := io.ReadAll(res.Body)
193+
err = apijson.Unmarshal(bytes, &env)
194+
if err != nil {
195+
resp.Diagnostics.AddError("failed to deserialize http request", err.Error())
196+
return
197+
}
198+
data = &env.Result
199+
200+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
201+
}
202+
203+
func (r *CustomPagesResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
204+
205+
}
206+
207+
func (r *CustomPagesResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
208+
if req.State.Raw.IsNull() {
209+
resp.Diagnostics.AddWarning(
210+
"Resource Destruction Considerations",
211+
"This resource cannot be destroyed from Terraform. If you create this resource, it will be "+
212+
"present in the API until manually deleted.",
213+
)
214+
}
215+
if req.Plan.Raw.IsNull() {
216+
resp.Diagnostics.AddWarning(
217+
"Resource Destruction Considerations",
218+
"Applying this resource destruction will remove the resource from the Terraform state "+
219+
"but will not change it in the API. If you would like to destroy or reset this resource "+
220+
"in the API, refer to the documentation for how to do it manually.",
221+
)
222+
}
223+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages_test
4+
5+
import (
6+
"context"
7+
"testing"
8+
9+
"github.com/cloudflare/terraform-provider-cloudflare/internal/services/custom_pages"
10+
"github.com/cloudflare/terraform-provider-cloudflare/internal/test_helpers"
11+
)
12+
13+
func TestCustomPagesModelSchemaParity(t *testing.T) {
14+
t.Parallel()
15+
model := (*custom_pages.CustomPagesModel)(nil)
16+
schema := custom_pages.ResourceSchema(context.TODO())
17+
errs := test_helpers.ValidateResourceModelSchemaIntegrity(model, schema)
18+
errs.Report(t)
19+
}
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package custom_pages
4+
5+
import (
6+
"context"
7+
8+
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
9+
"github.com/hashicorp/terraform-plugin-framework/resource"
10+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
11+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
12+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
13+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
14+
)
15+
16+
var _ resource.ResourceWithConfigValidators = (*CustomPagesResource)(nil)
17+
18+
func ResourceSchema(ctx context.Context) schema.Schema {
19+
return schema.Schema{
20+
Attributes: map[string]schema.Attribute{
21+
"identifier": schema.StringAttribute{
22+
Description: "Identifier",
23+
Required: true,
24+
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
25+
},
26+
"account_id": schema.StringAttribute{
27+
Description: "The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.",
28+
Optional: true,
29+
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
30+
},
31+
"zone_id": schema.StringAttribute{
32+
Description: "The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.",
33+
Optional: true,
34+
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
35+
},
36+
"state": schema.StringAttribute{
37+
Description: "The custom page state.\nAvailable values: \"default\", \"customized\".",
38+
Required: true,
39+
Validators: []validator.String{
40+
stringvalidator.OneOfCaseInsensitive("default", "customized"),
41+
},
42+
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
43+
},
44+
"url": schema.StringAttribute{
45+
Description: "The URL associated with the custom page.",
46+
Required: true,
47+
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
48+
},
49+
},
50+
}
51+
}
52+
53+
func (r *CustomPagesResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
54+
resp.Schema = ResourceSchema(ctx)
55+
}
56+
57+
func (r *CustomPagesResource) ConfigValidators(_ context.Context) []resource.ConfigValidator {
58+
return []resource.ConfigValidator{}
59+
}

0 commit comments

Comments
 (0)
Please sign in to comment.