Require nonblank notification identities
This commit is contained in:
@@ -135,6 +135,9 @@ Distributor notification is disabled by default. Its fields are:
|
||||
The upload token is read from the environment variable named by `token_env`.
|
||||
Use `secrets.directory` when a file-backed secret is appropriate.
|
||||
|
||||
When notification is enabled, each rendered single-report pipeline ID, bundle
|
||||
ID, and idempotency key must contain at least one non-whitespace character.
|
||||
|
||||
Single-report bundle templates accept `location_id`, `report_id`, `run_id`,
|
||||
`artifact_group`, `batch_output_name`, `valid_start_date`, `valid_end_date`,
|
||||
`valid_start_time`, `valid_end_time`, `valid_start_stamp`, `valid_end_stamp`,
|
||||
|
||||
@@ -23,8 +23,8 @@ A successful response is `202 Accepted` with JSON containing `run_id` and
|
||||
`status`. Acceptance means Distributor staged and validated the source bundle;
|
||||
it does not mean downstream destinations have published it.
|
||||
|
||||
The adapter requires a pipeline ID, bundle ID, idempotency key, and at least one
|
||||
source-file mapping before calling Distributor. It reads the bearer token from
|
||||
The adapter requires nonblank pipeline ID, bundle ID, and idempotency key, plus
|
||||
at least one source-file mapping, before calling Distributor. It reads the bearer token from
|
||||
the configured environment variable and redacts that value from errors. Request
|
||||
construction and timeout handling belong to the [Distributor adapter](../../internal/distributor-adapter.md).
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ returns a failed batch status even when all report counters show success; the
|
||||
top-level notification result contains the delivery diagnostic.
|
||||
|
||||
For a single report, Distributor notification follows the atomic output write.
|
||||
Enabled notification templates are validated before report processing, including
|
||||
the requirement that each rendered identity contains a non-whitespace character.
|
||||
See the [configuration reference](config.md) for pipeline, bundle,
|
||||
idempotency-key, and per-report path templates.
|
||||
|
||||
|
||||
@@ -1285,6 +1285,13 @@ func TestEnabledDistributorNotifyValidation(t *testing.T) {
|
||||
},
|
||||
wantErr: "notify.distributor.bundle_id_template",
|
||||
},
|
||||
{
|
||||
name: "BundleTemplateRenderedEmpty",
|
||||
mutate: func(cfg *Config) {
|
||||
cfg.Notify.Distributor.BundleIDTemplate = " "
|
||||
},
|
||||
wantErr: "notify.distributor.bundle_id_template",
|
||||
},
|
||||
{
|
||||
name: "IdempotencyTemplate",
|
||||
mutate: func(cfg *Config) {
|
||||
@@ -1292,6 +1299,13 @@ func TestEnabledDistributorNotifyValidation(t *testing.T) {
|
||||
},
|
||||
wantErr: "notify.distributor.idempotency_key_template",
|
||||
},
|
||||
{
|
||||
name: "IdempotencyTemplateRenderedEmpty",
|
||||
mutate: func(cfg *Config) {
|
||||
cfg.Notify.Distributor.IdempotencyKeyTemplate = " "
|
||||
},
|
||||
wantErr: "notify.distributor.idempotency_key_template",
|
||||
},
|
||||
{
|
||||
name: "BatchTemplate",
|
||||
mutate: func(cfg *Config) {
|
||||
|
||||
@@ -78,7 +78,14 @@ var distributorBatchIdempotencyTemplateVariables = map[string]struct{}{
|
||||
var distributorBatchPipelineTemplateVariables = distributorBatchTemplateVariables
|
||||
|
||||
func RenderDistributorBundleID(template string, values DistributorTemplateValues) (string, error) {
|
||||
return renderDistributorTemplate("notify.distributor.bundle_id_template", template, values, distributorTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.bundle_id_template", template, values, distributorTemplateVariables)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if strings.TrimSpace(rendered) == "" {
|
||||
return "", fmt.Errorf("notify.distributor.bundle_id_template renders an empty bundle id")
|
||||
}
|
||||
return rendered, nil
|
||||
}
|
||||
|
||||
func RenderDistributorPipelineID(template string, values DistributorTemplateValues) (string, error) {
|
||||
@@ -93,7 +100,14 @@ func RenderDistributorPipelineID(template string, values DistributorTemplateValu
|
||||
}
|
||||
|
||||
func RenderDistributorIdempotencyKey(template string, values DistributorTemplateValues) (string, error) {
|
||||
return renderDistributorTemplate("notify.distributor.idempotency_key_template", template, values, distributorIdempotencyTemplateVariables)
|
||||
rendered, err := renderDistributorTemplate("notify.distributor.idempotency_key_template", template, values, distributorIdempotencyTemplateVariables)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if strings.TrimSpace(rendered) == "" {
|
||||
return "", fmt.Errorf("notify.distributor.idempotency_key_template renders an empty idempotency key")
|
||||
}
|
||||
return rendered, nil
|
||||
}
|
||||
|
||||
func RenderDistributorBatchBundleID(template string, values DistributorBatchTemplateValues) (string, error) {
|
||||
|
||||
@@ -152,6 +152,9 @@ func validateDistributorNotify(cfg DistributorNotifyConfig) error {
|
||||
if _, err := RenderDistributorPipelineID(cfg.PipelineIDTemplate, values); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := RenderDistributorIdempotencyKey(cfg.IdempotencyKeyTemplate, values); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateDistributorBatchNotify(cfg.Batch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user