From cb0749c7abef5783e4f8857f1f564377f64337c1 Mon Sep 17 00:00:00 2001 From: Chlins Zhang Date: Sun, 2 Apr 2023 15:33:33 +0800 Subject: [PATCH] fix: add default payload_format for http type webhook (#18445) 1. Add migration SQL to handle the lost payload format for old policies. 2. Set payload format to 'Default' if not specified for http webhook in the API handler. 3. Fix the migration sql of notification_job Fixes: #18401, #18453 Signed-off-by: chlins --- api/v2.0/swagger.yaml | 1 + .../postgresql/0110_2.8.0_schema.up.sql | 50 +++++++++++++++++-- src/server/v2.0/handler/webhook.go | 6 ++- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/api/v2.0/swagger.yaml b/api/v2.0/swagger.yaml index b0a212156..129c5599c 100644 --- a/api/v2.0/swagger.yaml +++ b/api/v2.0/swagger.yaml @@ -8553,6 +8553,7 @@ definitions: description: Whether or not to skip cert verify. payload_format: $ref: '#/definitions/PayloadFormatType' + description: The payload format of webhook, by default is Default for http type. WebhookPolicy: type: object description: The webhook policy object diff --git a/make/migrations/postgresql/0110_2.8.0_schema.up.sql b/make/migrations/postgresql/0110_2.8.0_schema.up.sql index 5dfd7cd59..55420b88e 100644 --- a/make/migrations/postgresql/0110_2.8.0_schema.up.sql +++ b/make/migrations/postgresql/0110_2.8.0_schema.up.sql @@ -91,6 +91,42 @@ SET enabled = false, description = 'Chartmuseum is deprecated in Harbor v2.8.0, because this notification policy only has event type about Chartmuseum, so please update or delete this notification policy.' WHERE event_types = '[]'; +/* insert the default payload_format for http type webhook target */ +WITH targets_expanded AS ( + -- Expand the JSON array of targets into separate rows + SELECT + id, + jsonb_array_elements(targets::jsonb) AS target + FROM + notification_policy +), +targets_updated AS ( + -- Update targets based on the specified conditions + SELECT + id, + jsonb_agg( + CASE + -- If target is HTTP and has no payload format, add "Default" + WHEN target->>'type' = 'http' AND NOT target ? 'payload_format' + THEN target || '{"payload_format":"Default"}'::jsonb + ELSE target + END + ) AS targets + FROM + targets_expanded + GROUP BY + id +) +-- Update the original table with the updated targets +UPDATE + notification_policy +SET + targets = targets_updated.targets +FROM + targets_updated +WHERE + notification_policy.id = targets_updated.id; + /* migrate the webhook job to execution and task as the webhook refactor since v2.8 */ DO $$ DECLARE @@ -102,14 +138,18 @@ DECLARE exec_id integer; extra_attrs json; BEGIN - if exists (select 1 from information_schema.tables where table_name = 'notification_job') then + IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'notification_job') THEN FOR job_group IN SELECT DISTINCT policy_id,event_type FROM notification_job WHERE event_type NOT IN ('UPLOAD_CHART', 'DOWNLOAD_CHART', 'DELETE_CHART') LOOP - SELECT * INTO job FROM notification_job WHERE - policy_id=job_group.policy_id - AND event_type=job_group.event_type - AND status IN ('stopped', 'finished', 'error') + SELECT * INTO job FROM notification_job + WHERE policy_id=job_group.policy_id + AND event_type=job_group.event_type + AND status IN ('stopped', 'finished', 'error') ORDER BY creation_time DESC LIMIT 1; + /* continue if no final status job found for this policy */ + IF job IS NULL THEN + CONTINUE; + END IF; /* convert vendor type */ IF job.notify_type = 'http' THEN vendor_type = 'WEBHOOK'; diff --git a/src/server/v2.0/handler/webhook.go b/src/server/v2.0/handler/webhook.go index 56f8988e6..22a14ffca 100644 --- a/src/server/v2.0/handler/webhook.go +++ b/src/server/v2.0/handler/webhook.go @@ -406,7 +406,7 @@ func (n *webhookAPI) validateTargets(policy *policy_model.Policy) (bool, error) if len(policy.Targets) == 0 { return false, errors.New(nil).WithMessage("empty notification target with policy %s", policy.Name).WithCode(errors.BadRequestCode) } - for _, target := range policy.Targets { + for i, target := range policy.Targets { url, err := utils.ParseEndpoint(target.Address) if err != nil { return false, errors.New(err).WithCode(errors.BadRequestCode) @@ -426,6 +426,10 @@ func (n *webhookAPI) validateTargets(policy *policy_model.Policy) (bool, error) if len(target.PayloadFormat) > 0 && !isPayloadFormatSupported(target.PayloadFormat) { return false, errors.New(nil).WithMessage("unsupported payload format type: %s", target.PayloadFormat).WithCode(errors.BadRequestCode) } + // set payload format to Default is not specified when the type is http + if len(target.PayloadFormat) == 0 && target.Type == "http" { + policy.Targets[i].PayloadFormat = "Default" + } } return true, nil }