diff --git a/app/services/projects/container_repository/delete_tags_service.rb b/app/services/projects/container_repository/delete_tags_service.rb index 6e323fae2bc0ce29f83e066ae30efba9f0d1e2df..23814edf19b5da1ac3525f784ceb8bb808e1541f 100644 --- a/app/services/projects/container_repository/delete_tags_service.rb +++ b/app/services/projects/container_repository/delete_tags_service.rb @@ -13,7 +13,7 @@ def execute(container_repository) end @tag_names = params[:tags] - return error('not tags specified') if @tag_names.blank? + return error('no tags specified') if @tag_names.blank? delete_tags end @@ -56,3 +56,5 @@ def container_expiration_policy? end end end + +Projects::ContainerRepository::DeleteTagsService.prepend_mod_with('Projects::ContainerRepository::DeleteTagsService') diff --git a/doc/user/compliance/audit_event_types.md b/doc/user/compliance/audit_event_types.md index 22e2f23064d3eb7f11ec050d9aacc5eee34333c0..1b95280b1ad4ae3b5585146a45ee4217c6b91fb6 100644 --- a/doc/user/compliance/audit_event_types.md +++ b/doc/user/compliance/audit_event_types.md @@ -192,6 +192,7 @@ Audit event types belong to the following product categories. |:------------|:------------|:------------------|:---------|:--------------|:--------------| | [`container_repository_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152967) | Triggered when a project's container registry is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project | | [`container_repository_deletion_marked`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152967) | Triggered when a project's container repository is marked for deletion| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project | +| [`container_repository_tags_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156066) | Triggered when a project's container repository tag is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project | ### Continuous delivery diff --git a/ee/app/services/ee/projects/container_repository/delete_tags_service.rb b/ee/app/services/ee/projects/container_repository/delete_tags_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..23ae6d9337ec88bc8766ebef4d1e56106c843ec1 --- /dev/null +++ b/ee/app/services/ee/projects/container_repository/delete_tags_service.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module EE + module Projects + module ContainerRepository + module DeleteTagsService + extend ::Gitlab::Utils::Override + + override :execute + def execute(container_repository) + result = super(container_repository) + + audit_event(container_repository, params[:tags]) if result[:status] == :success + + result + end + + private + + def audit_event(repository, tags) + message = "Container repository tags marked for deletion: #{tags.join(', ')}" + + audit_context = { + name: "container_repository_tags_deleted", + author: current_user, + scope: project, + target: repository, + message: message + } + ::Gitlab::Audit::Auditor.audit(audit_context) + end + end + end + end +end diff --git a/ee/config/audit_events/types/container_repository_tags_deleted.yml b/ee/config/audit_events/types/container_repository_tags_deleted.yml new file mode 100644 index 0000000000000000000000000000000000000000..92e678ea314a200359965e423eff0e1ab7a87ece --- /dev/null +++ b/ee/config/audit_events/types/container_repository_tags_deleted.yml @@ -0,0 +1,10 @@ +--- +name: container_repository_tags_deleted +description: Triggered when a project's container repository tag is deleted +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/362290 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156066 +feature_category: container_registry +milestone: '17.2' +saved_to_database: true +streamed: true +scope: [Project] diff --git a/ee/spec/services/projects/container_repository/delete_tags_service_spec.rb b/ee/spec/services/projects/container_repository/delete_tags_service_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..a965118e70267aef06ee4de06e202dea77239f9a --- /dev/null +++ b/ee/spec/services/projects/container_repository/delete_tags_service_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::ContainerRepository::DeleteTagsService, feature_category: :container_registry do + describe '#resolve' do + using RSpec::Parameterized::TableSyntax + + include_context 'container repository delete tags service shared context' + + let(:tags) { %w[a b c] } + let(:subject) { described_class.new(project, user, params) } + + before do + allow(repository.client).to receive(:supports_tag_delete?).and_return(true) + stub_delete_reference_requests(tags) + project.add_developer(user) + end + + include_examples 'audit event logging' do + let(:operation) { subject.execute(repository) } + let(:event_type) { 'container_repository_tags_deleted' } + let(:fail_condition!) do + allow_next_instance_of(::Projects::ContainerRepository::Gitlab::DeleteTagsService) do |instance| + allow(instance).to receive(:execute).and_return({ status: :error }) + end + end + + let(:author) { user } + + let(:attributes) do + { + author_id: author.id, + entity_id: repository.project.id, + entity_type: 'Project', + details: { + event_name: "container_repository_tags_deleted", + author_class: author.class.to_s, + author_name: author.name, + custom_message: "Container repository tags marked for deletion: #{tags.join(', ')}", + target_details: repository.name, + target_id: repository.id, + target_type: repository.class.to_s + } + } + end + end + end +end