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 }