Skip to content

[datadog_cost_budget] add support for cost budgets #3001

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

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions datadog/fwprovider/data_source_datadog_cost_budget.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package fwprovider

import (
"context"

"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

type costBudgetDataSource struct {
Api *datadogV2.CloudCostManagementApi
Auth context.Context
}

func NewCostBudgetDataSource() datasource.DataSource {
return &costBudgetDataSource{}
}

type costBudgetDataSourceModel struct {
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
MetricsQuery types.String `tfsdk:"metrics_query"`
StartMonth types.Int64 `tfsdk:"start_month"`
EndMonth types.Int64 `tfsdk:"end_month"`
TotalAmount types.Float64 `tfsdk:"total_amount"`
Entries []budgetEntry `tfsdk:"entries"`
}

func (d *costBudgetDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = "cost_budget"
}

func (d *costBudgetDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Use this data source to retrieve information about an existing Datadog cost budget.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "The ID of the budget.",
Required: true,
},
"name": schema.StringAttribute{
Description: "The name of the budget.",
Computed: true,
},
"metrics_query": schema.StringAttribute{
Description: "The cost query used to track against the budget.",
Computed: true,
},
"start_month": schema.Int64Attribute{
Description: "The month when the budget starts (YYYYMM).",
Computed: true,
},
"end_month": schema.Int64Attribute{
Description: "The month when the budget ends (YYYYMM).",
Computed: true,
},
"total_amount": schema.Float64Attribute{
Description: "The sum of all budget entries' amounts.",
Computed: true,
},
},
Blocks: map[string]schema.Block{
"entries": schema.ListNestedBlock{
Description: "The entries of the budget.",
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
"amount": schema.Float64Attribute{
Computed: true,
},
"month": schema.Int64Attribute{
Computed: true,
},
},
Blocks: map[string]schema.Block{
"tag_filters": schema.ListNestedBlock{
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
"tag_key": schema.StringAttribute{Computed: true},
"tag_value": schema.StringAttribute{Computed: true},
},
},
},
},
},
},
},
}
}

func (d *costBudgetDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
providerData := req.ProviderData.(*FrameworkProvider)
d.Api = providerData.DatadogApiInstances.GetCloudCostManagementApiV2()
d.Auth = providerData.Auth
}

func (d *costBudgetDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var state costBudgetDataSourceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

apiResp, _, err := d.Api.GetBudget(d.Auth, state.ID.ValueString())
if err != nil {
resp.Diagnostics.AddError("Error reading budget", err.Error())
return
}

setDataSourceModelFromBudgetWithEntries(&state, apiResp)

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

func setDataSourceModelFromBudgetWithEntries(model *costBudgetDataSourceModel, apiResp datadogV2.BudgetWithEntries) {
if apiResp.Data == nil || apiResp.Data.Attributes == nil {
return
}
data := apiResp.Data
attr := data.Attributes

// Set top-level fields
if data.Id != nil {
model.ID = types.StringValue(*data.Id)
}
if attr.Name != nil {
model.Name = types.StringValue(*attr.Name)
}
if attr.MetricsQuery != nil {
model.MetricsQuery = types.StringValue(*attr.MetricsQuery)
}
if attr.StartMonth != nil {
model.StartMonth = types.Int64Value(*attr.StartMonth)
}
if attr.EndMonth != nil {
model.EndMonth = types.Int64Value(*attr.EndMonth)
}
if attr.TotalAmount != nil {
model.TotalAmount = types.Float64Value(*attr.TotalAmount)
}

// Set entries
var entries []budgetEntry
for _, apiEntry := range attr.Entries {
var tagFilters []tagFilter
for _, tf := range apiEntry.TagFilters {
var tagKey, tagValue types.String
if tf.TagKey != nil {
tagKey = types.StringValue(*tf.TagKey)
} else {
tagKey = types.StringNull()
}
if tf.TagValue != nil {
tagValue = types.StringValue(*tf.TagValue)
} else {
tagValue = types.StringNull()
}
tagFilters = append(tagFilters, tagFilter{
TagKey: tagKey,
TagValue: tagValue,
})
}

var amount types.Float64
if apiEntry.Amount != nil {
amount = types.Float64Value(*apiEntry.Amount)
} else {
amount = types.Float64Null()
}
var month types.Int64
if apiEntry.Month != nil {
month = types.Int64Value(*apiEntry.Month)
} else {
month = types.Int64Null()
}

entries = append(entries, budgetEntry{
Amount: amount,
Month: month,
TagFilters: tagFilters,
})
}
model.Entries = entries
}
2 changes: 2 additions & 0 deletions datadog/fwprovider/framework_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ var Resources = []func() resource.Resource{
NewAppBuilderAppResource,
NewObservabilitPipelineResource,
NewSecurityMonitoringRuleJSONResource,
NewCostBudgetResource,
}

var Datasources = []func() datasource.DataSource{
Expand Down Expand Up @@ -117,6 +118,7 @@ var Datasources = []func() datasource.DataSource{
NewDatadogSyntheticsLocationsDataSource,
NewWorkflowAutomationDataSource,
NewDatadogAppBuilderAppDataSource,
NewCostBudgetDataSource,
}

// FrameworkProvider struct
Expand Down
Loading
Loading