Skip to content

Commit ae5c3a5

Browse files
authored
Merge pull request #154 from matokovacik/main
Fix #153
2 parents 13ad19b + 5ae80bc commit ae5c3a5

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

docs/data-sources/resource.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ data "restful_resource" "test" {
2828
### Optional
2929

3030
- `allow_not_exist` (Boolean) Whether to throw error if the data source being queried doesn't exist (i.e. status code is 404). Defaults to `false`.
31+
- `body` (Dynamic) The request body that is sent when using `POST` method.
3132
- `header` (Map of String) The header parameters that are applied to each request. This overrides the `header` set in the provider block.
3233
- `method` (String) The HTTP Method for the request. Allowed methods are a subset of methods defined in [RFC7231](https://datatracker.ietf.org/doc/html/rfc7231#section-4.3) namely, `GET`, `HEAD`, and `POST`. `POST` support is only intended for read-only URLs, such as submitting a search. Defaults to `GET`.
3334
- `output_attrs` (Set of String) A set of `output` attribute paths (in [gjson syntax](https://github.com/tidwall/gjson/blob/master/SYNTAX.md)) that will be exported in the `output`. If this is not specified, all attributes will be exported by `output`.

internal/client/client.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,17 @@ type ReadOptionDS struct {
340340
Header Header
341341
}
342342

343-
func (c *Client) ReadDS(ctx context.Context, path string, opt ReadOptionDS) (*resty.Response, error) {
343+
func (c *Client) ReadDS(ctx context.Context, path string, body []byte, opt ReadOptionDS) (*resty.Response, error) {
344344
req := c.R().SetContext(ctx)
345345
req.SetQueryParamsFromValues(url.Values(opt.Query))
346346
req.SetHeaders(opt.Header)
347347

348+
// Set the body for POST requests if provided
349+
if len(body) != 0 && opt.Method == "POST" {
350+
req = req.SetHeader("Content-Type", "application/json")
351+
req = req.SetBody(body)
352+
}
353+
348354
switch opt.Method {
349355
case "", "GET":
350356
return req.Get(path)

internal/provider/data_source.go

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type dataSourceData struct {
2626
Method types.String `tfsdk:"method"`
2727
Query types.Map `tfsdk:"query"`
2828
Header types.Map `tfsdk:"header"`
29+
Body types.Dynamic `tfsdk:"body"`
2930
Selector types.String `tfsdk:"selector"`
3031
OutputAttrs types.Set `tfsdk:"output_attrs"`
3132
AllowNotExist types.Bool `tfsdk:"allow_not_exist"`
@@ -67,6 +68,11 @@ func (d *DataSource) Schema(ctx context.Context, req datasource.SchemaRequest, r
6768
ElementType: types.StringType,
6869
Optional: true,
6970
},
71+
"body": schema.DynamicAttribute{
72+
Description: "The request body that is sent when using `POST` method.",
73+
MarkdownDescription: "The request body that is sent when using `POST` method.",
74+
Optional: true,
75+
},
7076
"selector": schema.StringAttribute{
7177
Description: "A selector in gjson query syntax, that is used when `id` represents a collection of resources, to select exactly one member resource of from it",
7278
MarkdownDescription: "A selector in [gjson query syntax](https://github.com/tidwall/gjson/blob/master/SYNTAX.md#queries), that is used when `id` represents a collection of resources, to select exactly one member resource of from it",
@@ -93,6 +99,25 @@ func (d *DataSource) Schema(ctx context.Context, req datasource.SchemaRequest, r
9399
}
94100
}
95101

102+
func (d *DataSource) ValidateConfig(ctx context.Context, req datasource.ValidateConfigRequest, resp *datasource.ValidateConfigResponse) {
103+
var config dataSourceData
104+
diags := req.Config.Get(ctx, &config)
105+
resp.Diagnostics.Append(diags...)
106+
if diags.HasError() {
107+
return
108+
}
109+
if !config.Body.IsUnknown() && !config.Body.IsNull() {
110+
if !config.Method.IsUnknown() {
111+
if config.Method.ValueString() != "POST" {
112+
resp.Diagnostics.AddError(
113+
"Invalid configuration",
114+
"`body` is only applicable when `method` is set to `POST`",
115+
)
116+
}
117+
}
118+
}
119+
}
120+
96121
func (d *DataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
97122
if req.ProviderData == nil {
98123
return
@@ -140,15 +165,31 @@ func (d *DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp
140165

141166
state := dataSourceData{
142167
ID: config.ID,
168+
Method: config.Method,
143169
Query: config.Query,
144170
Header: config.Header,
171+
Body: config.Body,
145172
Selector: config.Selector,
146173
OutputAttrs: config.OutputAttrs,
147174
AllowNotExist: config.AllowNotExist,
148175
Precheck: config.Precheck,
149176
}
150177

151-
response, err := c.ReadDS(ctx, config.ID.ValueString(), *opt)
178+
// Set body if provided
179+
var body []byte
180+
if !config.Body.IsNull() && config.Method.ValueString() == "POST" {
181+
var err error
182+
body, err = dynamic.ToJSON(config.Body)
183+
if err != nil {
184+
resp.Diagnostics.AddError(
185+
"Error to convert body",
186+
err.Error(),
187+
)
188+
return
189+
}
190+
}
191+
192+
response, err := c.ReadDS(ctx, config.ID.ValueString(), body, *opt)
152193
if err != nil {
153194
resp.Diagnostics.AddError(
154195
"Error to call Read",

0 commit comments

Comments
 (0)