Mechanical, low-risk follow-up -- no new architectural question, no new
external service, no new write path. Each of sentry_dashboard,
sentry_alert_rule, and sentry_notification_target gets a matching data
source: a single Required id attribute in, every other attribute
Computed out, backed by the exact same getDashboard/getRule/
getNotificationTarget client methods and dashboardModelFromAPI/
alertRuleModelFromAPI/notificationTargetModelFromAPI conversion
functions the resources already use and already have tests for -- these
data sources add no new client code at all, just a thin
datasource.DataSource wrapper reusing what Create/Read/Update/Delete
already exercise.
sentry_notification_target's data source carries the same secret
caveat its resource does (Sensitive, but alerting's GET /targets/{id}
returns it unredacted, so it's a real plaintext value in Terraform
state) -- named again here rather than assumed obvious from the
resource's own docs.
Verified: provider_test.go's new schema-validation tests confirm each
data source's id is Required and everything else Computed, no
Terraform binary needed. Three new real acceptance tests
(TestAccDashboardDataSource_basic and its two siblings) each create a
resource then look it up via the matching data source, using
resource.TestCheckResourceAttrPair to prove the data source's Read
actually agrees with what the resource wrote -- not just that both
compile. Skip-gated by TF_ACC same as the existing six acceptance
tests, and needs the same live api/alerting services this environment
has no Docker access to bring up, so not run here -- same disclosed gap
as everything else Docker-gated in this repo.
88 lines
3.2 KiB
Go
88 lines
3.2 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
|
)
|
|
|
|
var (
|
|
_ datasource.DataSource = &alertRuleDataSource{}
|
|
_ datasource.DataSourceWithConfigure = &alertRuleDataSource{}
|
|
)
|
|
|
|
func newAlertRuleDataSource() datasource.DataSource {
|
|
return &alertRuleDataSource{}
|
|
}
|
|
|
|
// alertRuleDataSource looks up an existing alert rule by ID -- see
|
|
// dashboardDataSource's doc comment for why this reuses
|
|
// alertRuleResourceModel/alertRuleModelFromAPI rather than a parallel
|
|
// type.
|
|
type alertRuleDataSource struct {
|
|
client *client
|
|
}
|
|
|
|
func (d *alertRuleDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
|
resp.TypeName = req.ProviderTypeName + "_alert_rule"
|
|
}
|
|
|
|
func (d *alertRuleDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
|
resp.Schema = schema.Schema{
|
|
Description: "Looks up an existing Sentry alert rule by ID. See the sentry_alert_rule resource for how one is created/managed.",
|
|
Attributes: map[string]schema.Attribute{
|
|
"id": schema.StringAttribute{
|
|
Required: true,
|
|
Description: "Rule ID to look up.",
|
|
},
|
|
"tenant_id": schema.StringAttribute{Computed: true},
|
|
"name": schema.StringAttribute{Computed: true},
|
|
"description": schema.StringAttribute{Computed: true},
|
|
"query": schema.StringAttribute{Computed: true},
|
|
"query_language": schema.StringAttribute{Computed: true},
|
|
"condition_type": schema.StringAttribute{Computed: true},
|
|
"comparator": schema.StringAttribute{Computed: true},
|
|
"threshold_value": schema.Float64Attribute{Computed: true},
|
|
"eval_interval_seconds": schema.Int64Attribute{Computed: true},
|
|
"for_minutes": schema.Int64Attribute{Computed: true},
|
|
"renotify_interval_minutes": schema.Int64Attribute{Computed: true},
|
|
"notification_target_id": schema.StringAttribute{Computed: true},
|
|
"enabled": schema.BoolAttribute{Computed: true},
|
|
"created_by": schema.StringAttribute{Computed: true},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (d *alertRuleDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
|
if req.ProviderData == nil {
|
|
return
|
|
}
|
|
data, ok := req.ProviderData.(*providerData)
|
|
if !ok {
|
|
resp.Diagnostics.AddError(
|
|
"Unexpected Data Source Configure Type",
|
|
fmt.Sprintf("Expected *provider.providerData, got: %T. This is a provider bug -- please report it.", req.ProviderData),
|
|
)
|
|
return
|
|
}
|
|
d.client = data.alerting
|
|
}
|
|
|
|
func (d *alertRuleDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
|
var config alertRuleResourceModel
|
|
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
out, err := d.client.getRule(ctx, config.ID.ValueString())
|
|
if err != nil {
|
|
resp.Diagnostics.AddError("Reading Alert Rule", err.Error())
|
|
return
|
|
}
|
|
|
|
resp.Diagnostics.Append(resp.State.Set(ctx, alertRuleModelFromAPI(out))...)
|
|
}
|