From 72753c17a80ae003bbbd382c9dee00e61935e8b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Schr=C3=B6ter?= Date: Tue, 5 Nov 2024 15:00:52 +0100 Subject: [PATCH] [api] Adding support to wipe via token Introduce a Wipe token, esp to allow to rebuild patchinfo's which require a wipe in non-incident projects. --- docs/api/api/tokenlist.rng | 1 + .../controllers/person/token_controller.rb | 2 +- src/api/app/controllers/trigger/errors.rb | 2 +- src/api/app/controllers/trigger_controller.rb | 7 ++- .../app/lib/backend/api/sources/package.rb | 5 ++ src/api/app/models/token.rb | 2 + src/api/app/models/token/wipe.rb | 47 +++++++++++++++++++ src/api/app/policies/token/wipe_policy.rb | 8 ++++ src/api/config/routes/api.rb | 1 + src/api/public/apidocs/OBS-v2.10.50.yaml | 2 + .../apidocs/paths/person_login_token.yaml | 2 +- .../public/apidocs/paths/trigger_wipe.yaml | 9 ++++ 12 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 src/api/app/models/token/wipe.rb create mode 100644 src/api/app/policies/token/wipe_policy.rb create mode 100644 src/api/public/apidocs/paths/trigger_wipe.yaml diff --git a/docs/api/api/tokenlist.rng b/docs/api/api/tokenlist.rng index 819edb728eb..c75de38c0c8 100644 --- a/docs/api/api/tokenlist.rng +++ b/docs/api/api/tokenlist.rng @@ -81,6 +81,7 @@ - rebuild: trigger rebuilds of packages - release: trigger project releases - runservice: run a service via the POST /trigger/runservice route + - wipe: trigger wipe of binary artifacts - workflow: trigger SCM/CI workflows, see https://openbuildservice.org/help/manuals/obs-user-guide/cha-obs-scm-ci-workflow-integration diff --git a/src/api/app/controllers/person/token_controller.rb b/src/api/app/controllers/person/token_controller.rb index ad71d7b7dff..dcee7ef49f3 100644 --- a/src/api/app/controllers/person/token_controller.rb +++ b/src/api/app/controllers/person/token_controller.rb @@ -59,7 +59,7 @@ def validate_operation # - webUI: https://github.com/openSUSE/open-build-service/blob/master/src/api/app/models/token.rb#L27 # - API: https://github.com/openSUSE/open-build-service/blob/master/src/api/public/apidocs/paths/person_login_token.yaml#L89 return if operation_param.nil? || - %w[runservice rebuild release workflow].include?(operation_param) # possible API parameter values + %w[runservice rebuild release wipe workflow].include?(operation_param) # possible API parameter values render_error status: 400, errorcode: 'invalid_token_type', diff --git a/src/api/app/controllers/trigger/errors.rb b/src/api/app/controllers/trigger/errors.rb index 932f64a7817..39294243858 100644 --- a/src/api/app/controllers/trigger/errors.rb +++ b/src/api/app/controllers/trigger/errors.rb @@ -16,6 +16,6 @@ class BadSCMPayload < APIError end class MissingPackage < APIError - setup 'bad_request', 400, 'A package must be provided for the operations rebuild, release and runservice' + setup 'bad_request', 400, 'A package must be provided for the operations rebuild, release, wipe and runservice' end end diff --git a/src/api/app/controllers/trigger_controller.rb b/src/api/app/controllers/trigger_controller.rb index 07a0840b668..cf37e1d5dbc 100644 --- a/src/api/app/controllers/trigger_controller.rb +++ b/src/api/app/controllers/trigger_controller.rb @@ -52,13 +52,18 @@ def runservice create end + # validate_token_type callback uses the action_name + def wipe + create + end + private def validate_parameters_by_token case @token.type when 'Token::Workflow' raise InvalidToken, 'Invalid token found' - when 'Token::Rebuild', 'Token::Release' + when 'Token::Rebuild', 'Token::Release', 'Token::Wipe' return if params[:project].present? when 'Token::Service' return if params[:project].present? && params[:package].present? diff --git a/src/api/app/lib/backend/api/sources/package.rb b/src/api/app/lib/backend/api/sources/package.rb index 6011295aedf..d4368e83ac4 100644 --- a/src/api/app/lib/backend/api/sources/package.rb +++ b/src/api/app/lib/backend/api/sources/package.rb @@ -140,6 +140,11 @@ def self.file(project_name, package_name, file_name) http_get(['/source/:project/:package/:filename', project_name, package_name, file_name]) end + def self.wipe_binaries(project_name, package_name, options = {}) + http_post(['/build/:project', project_name], defaults: { cmd: :wipe, package: package_name }, + params: options.compact, accepted: %i[repository arch]) + end + # Writes the content of the source file # @return [String] def self.write_file(project_name, package_name, file_name, content = '', params = {}) diff --git a/src/api/app/models/token.rb b/src/api/app/models/token.rb index eeeef636b39..f5ef457e86b 100644 --- a/src/api/app/models/token.rb +++ b/src/api/app/models/token.rb @@ -40,6 +40,8 @@ def self.token_type(action) Token::Rebuild when 'release' Token::Release + when 'wipe' + Token::Wipe when 'workflow' Token::Workflow else diff --git a/src/api/app/models/token/wipe.rb b/src/api/app/models/token/wipe.rb new file mode 100644 index 00000000000..35b070efd6d --- /dev/null +++ b/src/api/app/models/token/wipe.rb @@ -0,0 +1,47 @@ +class Token::Wipe < Token + def call(options) + set_triggered_at + package_name = options[:package].to_param + package_name += ":#{options[:multibuild_flavor]}" if options[:multibuild_flavor] + if package_name.present? + Backend::Api::Sources::Package.wipe_binaries(options[:project].to_param, + package_name, + options.slice(:repository, :arch).compact) + else + Backend::Api::Build::Project.wipe_binaries(options[:project].to_param, + options.slice(:repository, :arch).compact) + end + end + + def package_find_options + { use_source: false, follow_multibuild: true } + end +end + +# == Schema Information +# +# Table name: tokens +# +# id :integer not null, primary key +# description :string(64) default("") +# scm_token :string(255) indexed +# string :string(255) indexed +# triggered_at :datetime +# type :string(255) +# workflow_configuration_path :string(255) default(".obs/workflows.yml") +# workflow_configuration_url :string(8192) +# executor_id :integer not null, indexed +# package_id :integer indexed +# +# Indexes +# +# index_tokens_on_scm_token (scm_token) +# index_tokens_on_string (string) UNIQUE +# package_id (package_id) +# user_id (executor_id) +# +# Foreign Keys +# +# tokens_ibfk_1 (executor_id => users.id) +# tokens_ibfk_2 (package_id => packages.id) +# diff --git a/src/api/app/policies/token/wipe_policy.rb b/src/api/app/policies/token/wipe_policy.rb new file mode 100644 index 00000000000..35578292850 --- /dev/null +++ b/src/api/app/policies/token/wipe_policy.rb @@ -0,0 +1,8 @@ +class Token::WipePolicy < TokenPolicy + def trigger? + return false unless user.is_active? + return PackagePolicy.new(user, record.object_to_authorize).update? if record.object_to_authorize.is_a?(Package) + + ProjectPolicy.new(user, record.object_to_authorize).update? if record.object_to_authorize.is_a?(Project) + end +end diff --git a/src/api/config/routes/api.rb b/src/api/config/routes/api.rb index 9aae77c9ae2..081e52c9b6a 100644 --- a/src/api/config/routes/api.rb +++ b/src/api/config/routes/api.rb @@ -72,6 +72,7 @@ post 'trigger/rebuild' => 'trigger#rebuild' post 'trigger/release' => 'trigger#release' post 'trigger/runservice' => 'trigger#runservice' + post 'trigger/wipe' => 'trigger#wipe' post 'trigger/workflow' => 'trigger_workflow#create' ### /issue_trackers diff --git a/src/api/public/apidocs/OBS-v2.10.50.yaml b/src/api/public/apidocs/OBS-v2.10.50.yaml index dafac659b66..5690b3ef9f6 100644 --- a/src/api/public/apidocs/OBS-v2.10.50.yaml +++ b/src/api/public/apidocs/OBS-v2.10.50.yaml @@ -517,6 +517,8 @@ paths: $ref: 'paths/trigger_release.yaml' /trigger/runservice: $ref: 'paths/trigger_runservice.yaml' + /trigger/wipe: + $ref: 'paths/trigger_wipe.yaml' /trigger/workflow: $ref: 'paths/trigger_workflow.yaml' /trigger/webhook: diff --git a/src/api/public/apidocs/paths/person_login_token.yaml b/src/api/public/apidocs/paths/person_login_token.yaml index d3435247add..da5d408ff46 100644 --- a/src/api/public/apidocs/paths/person_login_token.yaml +++ b/src/api/public/apidocs/paths/person_login_token.yaml @@ -86,7 +86,7 @@ post: name: operation schema: type: string - enum: [runservice, rebuild, release] + enum: [runservice, rebuild, release, wipe] description: | Operation indicates the kind of token that is going to be created. diff --git a/src/api/public/apidocs/paths/trigger_wipe.yaml b/src/api/public/apidocs/paths/trigger_wipe.yaml new file mode 100644 index 00000000000..e75de949ce9 --- /dev/null +++ b/src/api/public/apidocs/paths/trigger_wipe.yaml @@ -0,0 +1,9 @@ +post: + summary: Trigger a wipe of binary artifacts + description: | + This endpoint behaves exactly as the [/trigger](#/Trigger/post_trigger) endpoint but + only allows API tokens with the operation 'wipe' to be triggered. + security: + - GitLab_key_authentication: [] + tags: + - Trigger