terraform-provider-nautobot/internal/provider/data_source_graphql.go

82 lines
2.1 KiB
Go

package provider
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/tidwall/gjson"
)
func dataSourceGraphQL() *schema.Resource {
return &schema.Resource{
Description: "Provide an interface to make GraphQL calls to Nautobot as a flexible data source.",
ReadContext: dataSourceGraphQLRead,
Schema: map[string]*schema.Schema{
"query": {
Description: "The GraphQL query that will be sent to Nautobot.",
Type: schema.TypeString,
Required: true,
},
"data": {
Description: "The data returned by the GraphQL query.",
Type: schema.TypeString,
Computed: true,
},
},
}
}
type reqBody struct {
Query string `json:"query"`
}
// Use this as reference: https://learn.hashicorp.com/tutorials/terraform/provider-setup?in=terraform/providers#implement-read
func dataSourceGraphQLRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
c := meta.(*apiClient).BaseClient
s := fmt.Sprintf("%sgraphql/", meta.(*apiClient).Server)
t := meta.(*apiClient).Token
query := d.Get("query").(string)
queryBody, _ := json.Marshal(reqBody{Query: query})
req, err := http.NewRequestWithContext(ctx, "POST", s, bytes.NewBuffer(queryBody))
if err != nil {
return diag.Errorf("failed to create request with context %s: %s", s, err.Error())
}
req.Header.Add("Content-Type", "application/json")
// Add the authorization header to our request.
t.Intercept(ctx, req)
rsp, err := c.Client.Do(req)
if err != nil {
return diag.Errorf("failed to successfully call %s: %s", s, err.Error())
}
defer rsp.Body.Close()
body, err := io.ReadAll(rsp.Body)
if err != nil {
return diag.Errorf("failed to decode GraphQL response from %s: %s", s, err.Error())
}
data := gjson.Get(string(body), "data")
if err := d.Set("data", data.Raw); err != nil {
return diag.FromErr(err)
}
// always run
d.SetId(strconv.FormatInt(time.Now().Unix(), 10))
return diags
}