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 <chenyuzh@vmware.com>
This commit is contained in:
Chlins Zhang 2023-04-02 15:33:33 +08:00 committed by GitHub
parent 5d953b48b6
commit cb0749c7ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 6 deletions

View File

@ -8553,6 +8553,7 @@ definitions:
description: Whether or not to skip cert verify. description: Whether or not to skip cert verify.
payload_format: payload_format:
$ref: '#/definitions/PayloadFormatType' $ref: '#/definitions/PayloadFormatType'
description: The payload format of webhook, by default is Default for http type.
WebhookPolicy: WebhookPolicy:
type: object type: object
description: The webhook policy object description: The webhook policy object

View File

@ -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.' 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 = '[]'; 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 */ /* migrate the webhook job to execution and task as the webhook refactor since v2.8 */
DO $$ DO $$
DECLARE DECLARE
@ -102,14 +138,18 @@ DECLARE
exec_id integer; exec_id integer;
extra_attrs json; extra_attrs json;
BEGIN 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') 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 LOOP
SELECT * INTO job FROM notification_job WHERE SELECT * INTO job FROM notification_job
policy_id=job_group.policy_id WHERE policy_id=job_group.policy_id
AND event_type=job_group.event_type AND event_type=job_group.event_type
AND status IN ('stopped', 'finished', 'error') AND status IN ('stopped', 'finished', 'error')
ORDER BY creation_time DESC LIMIT 1; 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 */ /* convert vendor type */
IF job.notify_type = 'http' THEN IF job.notify_type = 'http' THEN
vendor_type = 'WEBHOOK'; vendor_type = 'WEBHOOK';

View File

@ -406,7 +406,7 @@ func (n *webhookAPI) validateTargets(policy *policy_model.Policy) (bool, error)
if len(policy.Targets) == 0 { if len(policy.Targets) == 0 {
return false, errors.New(nil).WithMessage("empty notification target with policy %s", policy.Name).WithCode(errors.BadRequestCode) 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) url, err := utils.ParseEndpoint(target.Address)
if err != nil { if err != nil {
return false, errors.New(err).WithCode(errors.BadRequestCode) 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) { if len(target.PayloadFormat) > 0 && !isPayloadFormatSupported(target.PayloadFormat) {
return false, errors.New(nil).WithMessage("unsupported payload format type: %s", target.PayloadFormat).WithCode(errors.BadRequestCode) 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 return true, nil
} }