123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- package provider
- import (
- "context"
- "fmt"
- "github.com/hashicorp-demoapp/hashicups-client-go"
- "github.com/hashicorp/terraform-plugin-framework/datasource"
- "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
- "github.com/hashicorp/terraform-plugin-framework/types"
- )
- // Ensure the implementation satisfies the expected interfaces.
- var (
- _ datasource.DataSource = &coffeesDataSource{}
- _ datasource.DataSourceWithConfigure = &coffeesDataSource{}
- )
- func NewCoffeesDataSource() datasource.DataSource {
- return &coffeesDataSource{}
- }
- type coffeesDataSource struct {
- client *hashicups.Client
- }
- func (d *coffeesDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
- // Add a nil check when handling ProviderData because Terraform
- // sets that data after it calls the ConfigureProvider RPC.
- if req.ProviderData == nil {
- return
- }
- client, ok := req.ProviderData.(*hashicups.Client)
- if !ok {
- resp.Diagnostics.AddError("Unexpected Data Source Configure Type",
- fmt.Sprintf("Expected *hashicups.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData))
- return
- }
- d.client = client
- }
- func (d *coffeesDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
- resp.TypeName = req.ProviderTypeName + "_coffees"
- }
- func (d *coffeesDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
- resp.Schema = schema.Schema{
- Attributes: map[string]schema.Attribute{
- "coffees": schema.ListNestedAttribute{
- Computed: true,
- NestedObject: schema.NestedAttributeObject{
- Attributes: map[string]schema.Attribute{
- "id": schema.Int64Attribute{
- Computed: true,
- },
- "name": schema.StringAttribute{
- Computed: true,
- },
- "teaser": schema.StringAttribute{
- Computed: true,
- },
- "description": schema.StringAttribute{
- Computed: true,
- },
- "price": schema.Float64Attribute{
- Computed: true,
- },
- "image": schema.StringAttribute{
- Computed: true,
- },
- "ingredients": schema.ListNestedAttribute{
- Computed: true,
- NestedObject: schema.NestedAttributeObject{
- Attributes: map[string]schema.Attribute{
- "id": schema.Int64Attribute{
- Computed: true,
- },
- },
- },
- },
- },
- },
- },
- },
- }
- }
- // Read is used by the data source to refresh the Terraform state based on the schema data.
- func (d *coffeesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
- // 1. Reads coffees list. The method invokes the API client's GetCoffees method.
- var state coffeesDataSourceModel
- coffees, err := d.client.GetCoffees()
- if err != nil {
- resp.Diagnostics.AddError(
- "Unable to Read HashiCups Coffees",
- err.Error(),
- )
- return
- }
- // 2. Maps response body to schema attributes.
- // After the method reads the coffees, it maps the []hashicups.Coffee response
- // to coffeesModel so the data source can set the Terraform state.
- for _, coffee := range coffees {
- coffeeState := coffeesModel{
- ID: types.Int64Value(int64(coffee.ID)),
- Name: types.StringValue(coffee.Name),
- Teaser: types.StringValue(coffee.Teaser),
- Description: types.StringValue(coffee.Description),
- Price: types.Float64Value(coffee.Price),
- Image: types.StringValue(coffee.Image),
- Ingredients: make([]coffeeIngredientsModel, 0, len(coffee.Ingredient)), // Not in tutorial, why ?
- }
- for _, ingredient := range coffee.Ingredient {
- coffeeState.Ingredients = append(coffeeState.Ingredients, coffeeIngredientsModel{
- ID: types.Int64Value(int64(ingredient.ID)),
- })
- }
- state.Coffees = append(state.Coffees, coffeeState)
- }
- // 3. Sets state with coffees list.
- diags := resp.State.Set(ctx, state)
- resp.Diagnostics.Append(diags...)
- // Useless code from tutorial, why ?
- if resp.Diagnostics.HasError() {
- return
- }
- }
- type coffeesDataSourceModel struct {
- Coffees []coffeesModel `tfsdk:"coffees"`
- }
- type coffeesModel struct {
- ID types.Int64 `tfsdk:"id"`
- Name types.String `tfsdk:"name"`
- Teaser types.String `tfsdk:"teaser"`
- Description types.String `tfsdk:"description"`
- Price types.Float64 `tfsdk:"price"`
- Image types.String `tfsdk:"image"`
- Ingredients []coffeeIngredientsModel `tfsdk:"ingredients"`
- }
- type coffeeIngredientsModel struct {
- ID types.Int64 `tfsdk:"id"`
- }
|