From a08a3bc93dbad683809b6684f32a5649d7e015a3 Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Wed, 8 Nov 2023 14:05:49 +0530 Subject: [PATCH 1/5] Added create api for namespace filters Added create api for adding namespace filters for group level custom http external audit event destination Changelog: added EE: true --- .../audit_event_types.md | 1 + doc/api/graphql/reference/index.md | 33 +++ ee/app/graphql/ee/types/mutation_type.rb | 1 + .../http/namespace_filters/create.rb | 90 +++++++ .../types/create_http_namespace_filter.yml | 8 + .../http/namespace_filters/create_spec.rb | 255 ++++++++++++++++++ 6 files changed, 388 insertions(+) create mode 100644 ee/app/graphql/mutations/audit_events/streaming/http/namespace_filters/create.rb create mode 100644 ee/config/audit_events/types/create_http_namespace_filter.yml create mode 100644 ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb diff --git a/doc/administration/audit_event_streaming/audit_event_types.md b/doc/administration/audit_event_streaming/audit_event_types.md index 34d19327c18b05..4165e60ab9c87b 100644 --- a/doc/administration/audit_event_streaming/audit_event_types.md +++ b/doc/administration/audit_event_streaming/audit_event_types.md @@ -45,6 +45,7 @@ Audit event types belong to the following product categories. | [`audit_events_streaming_instance_headers_destroy`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127228) | Triggered when a streaming header for instance level external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.3](https://gitlab.com/gitlab-org/gitlab/-/issues/417433) | | [`audit_events_streaming_instance_headers_update`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127228) | Triggered when a streaming header for instance level external audit event destination is updated| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.3](https://gitlab.com/gitlab-org/gitlab/-/issues/417433) | | [`create_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74632) | Event triggered when an external audit event destination is created| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/344664) | +| [`create_http_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136047) | Event triggered when a namespace filter for group level external audit event destination is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.6](https://gitlab.com/gitlab-org/gitlab/-/issues/424176) | | [`create_instance_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123882) | Event triggered when an instance level external audit event destination is created| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.2](https://gitlab.com/gitlab-org/gitlab/-/issues/404730) | | [`destroy_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74632) | Event triggered when an external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/344664) | | [`destroy_instance_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125846) | Event triggered when an instance level external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.2](https://gitlab.com/gitlab-org/gitlab/-/issues/404730) | diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 98c5d13e75a4eb..ed26bab8e126cf 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -1564,6 +1564,27 @@ Input type: `AuditEventsStreamingHeadersUpdateInput` | `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | `header` | [`AuditEventStreamingHeader`](#auditeventstreamingheader) | Updates header. | +### `Mutation.auditEventsStreamingHttpNamespaceFiltersAdd` + +Input type: `AuditEventsStreamingHTTPNamespaceFiltersAddInput` + +#### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| `destinationId` | [`AuditEventsExternalAuditEventDestinationID!`](#auditeventsexternalauditeventdestinationid) | Destination id. | +| `groupPath` | [`ID`](#id) | Group full path. | +| `projectPath` | [`ID`](#id) | Project full path. | + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | +| `namespaceFilter` | [`AuditEventStreamingHTTPNamespaceFilter`](#auditeventstreaminghttpnamespacefilter) | Namespace filter created. | + ### `Mutation.auditEventsStreamingInstanceHeadersCreate` Input type: `AuditEventsStreamingInstanceHeadersCreateInput` @@ -14073,6 +14094,18 @@ Represents a HTTP header key/value that belongs to an audit streaming destinatio | `key` | [`String!`](#string) | Key of the header. | | `value` | [`String!`](#string) | Value of the header. | +### `AuditEventsStreamingHTTPNamespaceFiltersAddPayload` + +Autogenerated return type of AuditEventsStreamingHTTPNamespaceFiltersAdd. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | +| `namespaceFilter` | [`AuditEventStreamingHTTPNamespaceFilter`](#auditeventstreaminghttpnamespacefilter) | Namespace filter created. | + ### `AuditEventsStreamingInstanceHeader` Represents a HTTP header key/value that belongs to an instance level audit streaming destination. diff --git a/ee/app/graphql/ee/types/mutation_type.rb b/ee/app/graphql/ee/types/mutation_type.rb index 4cd40ff64f2931..42ffa616070940 100644 --- a/ee/app/graphql/ee/types/mutation_type.rb +++ b/ee/app/graphql/ee/types/mutation_type.rb @@ -142,6 +142,7 @@ module MutationType mount_mutation ::Mutations::Analytics::CycleAnalytics::ValueStreams::Create, alpha: { milestone: '16.6' } mount_mutation ::Mutations::Analytics::CycleAnalytics::ValueStreams::Update, alpha: { milestone: '16.6' } mount_mutation ::Mutations::Analytics::CycleAnalytics::ValueStreams::Destroy, alpha: { milestone: '16.6' } + mount_mutation ::Mutations::AuditEvents::Streaming::HTTP::NamespaceFilters::Create prepend(Types::DeprecatedMutations) end diff --git a/ee/app/graphql/mutations/audit_events/streaming/http/namespace_filters/create.rb b/ee/app/graphql/mutations/audit_events/streaming/http/namespace_filters/create.rb new file mode 100644 index 00000000000000..a5a2bcd796ca17 --- /dev/null +++ b/ee/app/graphql/mutations/audit_events/streaming/http/namespace_filters/create.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module Mutations + module AuditEvents + module Streaming + module HTTP + module NamespaceFilters + class Create < BaseMutation + graphql_name 'AuditEventsStreamingHTTPNamespaceFiltersAdd' + authorize :admin_external_audit_events + + argument :destination_id, ::Types::GlobalIDType[::AuditEvents::ExternalAuditEventDestination], + required: true, + description: 'Destination id.' + + argument :group_path, GraphQL::Types::ID, + required: false, + description: 'Group full path.' + + argument :project_path, GraphQL::Types::ID, + required: false, + description: 'Project full path.' + + field :namespace_filter, ::Types::AuditEvents::Streaming::HTTP::NamespaceFilterType, + null: true, + description: 'Namespace filter created.' + + def ready?(**args) + if args.slice(*mutually_exclusive_args).size != 1 + arg_str = mutually_exclusive_args.map { |x| x.to_s.camelize(:lower) }.join(' or ') + raise Gitlab::Graphql::Errors::ArgumentError, "one and only one of #{arg_str} is required" + end + + super + end + + def resolve(args) + destination = authorized_find!(args[:destination_id]) + + namespace = namespace(args[:group_path], args[:project_path]) + + filter = ::AuditEvents::Streaming::HTTP::NamespaceFilter + .new(external_audit_event_destination: destination, + namespace: namespace) + + audit(filter, action: :create) if filter.save + + { namespace_filter: (filter if filter.persisted?), errors: Array(filter.errors) } + end + + private + + def find_object(destination_id) + ::GitlabSchema.object_from_id(destination_id, expected_type: ::AuditEvents::ExternalAuditEventDestination) + end + + def namespace(group_path, project_path) + if group_path.present? + namespace = ::Group.find_by_full_path(group_path) + raise_resource_not_available_error! 'group_path is invalid' if namespace.nil? + return namespace + end + + namespace = ::Project.find_by_full_path(project_path) + raise_resource_not_available_error! 'project_path is invalid' if namespace.nil? + namespace.project_namespace + end + + def audit(filter, action:) + audit_context = { + name: "#{action}_http_namespace_filter", + author: current_user, + scope: filter.external_audit_event_destination.group, + target: filter.external_audit_event_destination, + message: "#{action.capitalize} namespace filter for http audit event streaming destination " \ + "#{filter.external_audit_event_destination.name} and namespace #{filter.namespace.full_path}" + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + + def mutually_exclusive_args + [:group_path, :project_path] + end + end + end + end + end + end +end diff --git a/ee/config/audit_events/types/create_http_namespace_filter.yml b/ee/config/audit_events/types/create_http_namespace_filter.yml new file mode 100644 index 00000000000000..0d8ca218b9cc74 --- /dev/null +++ b/ee/config/audit_events/types/create_http_namespace_filter.yml @@ -0,0 +1,8 @@ +name: create_http_namespace_filter +description: Event triggered when a namespace filter for group level external audit event destination is created. +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/424176 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136047 +feature_category: audit_events +milestone: "16.6" +saved_to_database: true +streamed: true diff --git a/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb b/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb new file mode 100644 index 00000000000000..4ead0d87ac2a15 --- /dev/null +++ b/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb @@ -0,0 +1,255 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Create a namespace filter for group level external audit event destinations', feature_category: :audit_events do + include GraphqlHelpers + + let_it_be(:group) { create(:group) } + let(:destination) { create(:external_audit_event_destination, group: group) } + let_it_be(:current_user) { create(:user) } + let(:mutation) { graphql_mutation(:audit_events_streaming_http_namespace_filters_add, input) } + let(:mutation_response) { graphql_mutation_response(:audit_events_streaming_http_namespace_filters_add) } + + subject { post_graphql_mutation(mutation, current_user: current_user) } + + shared_examples 'does not create namespace filter' do + it do + expect(::Gitlab::Audit::Auditor).not_to receive(:audit) + + expect { subject }.not_to change { AuditEvents::Streaming::HTTP::NamespaceFilter.count } + + expect(graphql_errors).to include(a_hash_including('message' => error_message)) + expect(mutation_response).to eq(nil) + end + end + + context 'when feature is licensed' do + before do + stub_licensed_features(external_audit_events: true) + end + + context 'when current user is a group owner' do + before_all do + group.add_owner(current_user) + end + + shared_examples 'creation of namespace filters with one path' do + context 'when namespace is a descendant of the destination group' do + let(:input) do + { + destinationId: destination.to_gid, + "#{namespace_path.camelize(:lower)}": namespace.full_path + } + end + + it 'creates a namespace filter' do + expect(::Gitlab::Audit::Auditor).to receive(:audit).with(a_hash_including( + name: 'create_http_namespace_filter', + author: current_user, + scope: group, + target: destination, + message: "Create namespace filter for http audit event streaming destination #{destination.name} " \ + "and namespace #{namespace.full_path}")).once.and_call_original + + expect { subject } + .to change { AuditEvent.count }.by(1) + + expect_graphql_errors_to_be_empty + + namespace_filter = destination.namespace_filter + expect(namespace_filter.namespace).to eq(namespace) + expect(namespace_filter.external_audit_event_destination).to eq(destination) + + expect(mutation_response['errors']).to be_empty + expect(mutation_response).to have_key('namespaceFilter') + expect(mutation_response['namespaceFilter']['namespace']['fullPath']).to eq(namespace.full_path) + expect(mutation_response['namespaceFilter']['externalAuditEventDestination']['name']) + .to eq(destination.name) + end + + context 'when namespace filter for the destination already exists' do + it 'returns error' do + create(:audit_events_streaming_http_namespace_filter, external_audit_event_destination: destination, + namespace: create(:group, parent: group)) + + expect { subject }.not_to change { AuditEvents::Streaming::HTTP::NamespaceFilter.count } + expect(mutation_response['errors']) + .to match_array(['External audit event destination has already been taken']) + expect(mutation_response['namespaceFilter']).to be nil + end + end + + context 'when namespace filter for the given namespace already exists' do + it 'returns error' do + create(:audit_events_streaming_http_namespace_filter, + external_audit_event_destination: create(:external_audit_event_destination, group: group), + namespace: namespace + ) + + expect { subject }.not_to change { AuditEvents::Streaming::HTTP::NamespaceFilter.count } + expect(mutation_response['errors']).to match_array(['Namespace has already been taken']) + expect(mutation_response['namespaceFilter']).to be nil + end + end + end + + context 'when namespace group is not a descendant of the destination group' do + let(:input) do + { + destinationId: destination.to_gid, + "#{namespace_path.camelize(:lower)}": other_namespace.full_path + } + end + + it 'returns error' do + expect(::Gitlab::Audit::Auditor).not_to receive(:audit) + + expect { subject }.not_to change { AuditEvents::Streaming::HTTP::NamespaceFilter.count } + + expect(mutation_response).to include( + 'errors' => ['External audit event destination does not belong to the top-level group of the namespace.'] + ) + expect(mutation_response['namespaceFilter']).to eq(nil) + end + end + + context 'when given namespace path is invalid' do + let(:input) do + { + destinationId: destination.to_gid, + "#{namespace_path.camelize(:lower)}": 'invalid_path' + } + end + + it 'returns error' do + expect(::Gitlab::Audit::Auditor).not_to receive(:audit) + + expect { subject }.not_to change { AuditEvents::Streaming::HTTP::NamespaceFilter.count } + + expect(graphql_errors).to include(a_hash_including('message' => "#{namespace_path} is invalid")) + expect(mutation_response).to eq(nil) + end + end + end + + context 'when group_path is passed in params' do + it_behaves_like 'creation of namespace filters with one path' do + let_it_be(:namespace) { create(:group, parent: group) } + let_it_be(:other_namespace) { create(:group) } + let(:namespace_path) { "group_path" } + end + end + + context 'when project_path is passed in params' do + it_behaves_like 'creation of namespace filters with one path' do + let_it_be(:project) { create(:project, group: group) } + let_it_be(:namespace) { project.project_namespace } + let_it_be(:other_namespace) { create(:project_namespace) } + let(:namespace_path) { "project_path" } + end + end + + context 'when both group_path and project_path are passed in params' do + let_it_be(:namespace_group) { create(:group, parent: group) } + let_it_be(:namespace_project) { create(:project, group: group) } + + let(:input) do + { + destinationId: destination.to_gid, + projectPath: namespace_project.full_path, + groupPath: namespace_group.full_path + } + end + + let(:error_message) { 'one and only one of groupPath or projectPath is required' } + + it_behaves_like 'does not create namespace filter' + end + + context 'when none of group_path and project_path is passed in params' do + let(:input) do + { + destinationId: destination.to_gid + } + end + + let(:error_message) { 'one and only one of groupPath or projectPath is required' } + + it_behaves_like 'does not create namespace filter' + end + end + + context 'when current user is a group maintainer' do + before_all do + group.add_maintainer(current_user) + end + + let_it_be(:namespace_group) { create(:group, parent: group) } + let(:input) do + { + destinationId: destination.to_gid, + groupPath: namespace_group.full_path + } + end + + let(:error_message) { ::Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR } + + it_behaves_like 'does not create namespace filter' + end + + context 'when current user is a group developer' do + before_all do + group.add_developer(current_user) + end + + let_it_be(:namespace_group) { create(:group, parent: group) } + let(:input) do + { + destinationId: destination.to_gid, + groupPath: namespace_group.full_path + } + end + + let(:error_message) { ::Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR } + + it_behaves_like 'does not create namespace filter' + end + + context 'when current user is a group guest' do + before_all do + group.add_guest(current_user) + end + + let_it_be(:namespace_group) { create(:group, parent: group) } + let(:input) do + { + destinationId: destination.to_gid, + groupPath: namespace_group.full_path + } + end + + let(:error_message) { ::Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR } + + it_behaves_like 'does not create namespace filter' + end + end + + context 'when feature is unlicensed' do + before do + stub_licensed_features(external_audit_events: false) + end + + let_it_be(:namespace_group) { create(:group, parent: group) } + let(:input) do + { + destinationId: destination.to_gid, + groupPath: namespace_group.full_path + } + end + + let(:error_message) { ::Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR } + + it_behaves_like 'does not create namespace filter' + end +end -- GitLab From 8091021bc57b497fe68793e2f1920846d878aefd Mon Sep 17 00:00:00 2001 From: Evan Read Date: Thu, 9 Nov 2023 06:05:04 +0000 Subject: [PATCH 2/5] Applying documentation changes --- .../audit_events/streaming/http/namespace_filters/create.rb | 6 +++--- .../audit_events/types/create_http_namespace_filter.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ee/app/graphql/mutations/audit_events/streaming/http/namespace_filters/create.rb b/ee/app/graphql/mutations/audit_events/streaming/http/namespace_filters/create.rb index a5a2bcd796ca17..054d60d0cb3be1 100644 --- a/ee/app/graphql/mutations/audit_events/streaming/http/namespace_filters/create.rb +++ b/ee/app/graphql/mutations/audit_events/streaming/http/namespace_filters/create.rb @@ -11,15 +11,15 @@ class Create < BaseMutation argument :destination_id, ::Types::GlobalIDType[::AuditEvents::ExternalAuditEventDestination], required: true, - description: 'Destination id.' + description: 'Destination ID.' argument :group_path, GraphQL::Types::ID, required: false, - description: 'Group full path.' + description: 'Full path of the group.' argument :project_path, GraphQL::Types::ID, required: false, - description: 'Project full path.' + description: 'Full path of the project.' field :namespace_filter, ::Types::AuditEvents::Streaming::HTTP::NamespaceFilterType, null: true, diff --git a/ee/config/audit_events/types/create_http_namespace_filter.yml b/ee/config/audit_events/types/create_http_namespace_filter.yml index 0d8ca218b9cc74..b8de6328d07499 100644 --- a/ee/config/audit_events/types/create_http_namespace_filter.yml +++ b/ee/config/audit_events/types/create_http_namespace_filter.yml @@ -1,5 +1,5 @@ name: create_http_namespace_filter -description: Event triggered when a namespace filter for group level external audit event destination is created. +description: Event triggered when a namespace filter for an external audit event destination for a top-level group is created. introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/424176 introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136047 feature_category: audit_events -- GitLab From f3daa8bf26b18af3f231247cbff4a1590b51c42b Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Thu, 9 Nov 2023 11:50:50 +0530 Subject: [PATCH 3/5] Moved create to before block --- .../http/namespace_filters/create_spec.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb b/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb index 4ead0d87ac2a15..aae350a17010e3 100644 --- a/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb +++ b/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb @@ -55,12 +55,12 @@ expect { subject } .to change { AuditEvent.count }.by(1) - expect_graphql_errors_to_be_empty - namespace_filter = destination.namespace_filter expect(namespace_filter.namespace).to eq(namespace) expect(namespace_filter.external_audit_event_destination).to eq(destination) + expect_graphql_errors_to_be_empty + expect(mutation_response['errors']).to be_empty expect(mutation_response).to have_key('namespaceFilter') expect(mutation_response['namespaceFilter']['namespace']['fullPath']).to eq(namespace.full_path) @@ -69,11 +69,14 @@ end context 'when namespace filter for the destination already exists' do - it 'returns error' do + before do create(:audit_events_streaming_http_namespace_filter, external_audit_event_destination: destination, namespace: create(:group, parent: group)) + end + it 'returns error' do expect { subject }.not_to change { AuditEvents::Streaming::HTTP::NamespaceFilter.count } + expect(mutation_response['errors']) .to match_array(['External audit event destination has already been taken']) expect(mutation_response['namespaceFilter']).to be nil @@ -81,13 +84,16 @@ end context 'when namespace filter for the given namespace already exists' do - it 'returns error' do + before do create(:audit_events_streaming_http_namespace_filter, external_audit_event_destination: create(:external_audit_event_destination, group: group), namespace: namespace ) + end + it 'returns error' do expect { subject }.not_to change { AuditEvents::Streaming::HTTP::NamespaceFilter.count } + expect(mutation_response['errors']).to match_array(['Namespace has already been taken']) expect(mutation_response['namespaceFilter']).to be nil end -- GitLab From 25ac391278a4f2359502b6f6895ea37d6395f97f Mon Sep 17 00:00:00 2001 From: Hitesh Raghuvanshi Date: Thu, 9 Nov 2023 11:52:52 +0530 Subject: [PATCH 4/5] Updated autogenerated docs --- .../audit_event_streaming/audit_event_types.md | 2 +- doc/api/graphql/reference/index.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/administration/audit_event_streaming/audit_event_types.md b/doc/administration/audit_event_streaming/audit_event_types.md index 4165e60ab9c87b..f0abbd255962f3 100644 --- a/doc/administration/audit_event_streaming/audit_event_types.md +++ b/doc/administration/audit_event_streaming/audit_event_types.md @@ -45,7 +45,7 @@ Audit event types belong to the following product categories. | [`audit_events_streaming_instance_headers_destroy`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127228) | Triggered when a streaming header for instance level external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.3](https://gitlab.com/gitlab-org/gitlab/-/issues/417433) | | [`audit_events_streaming_instance_headers_update`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127228) | Triggered when a streaming header for instance level external audit event destination is updated| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.3](https://gitlab.com/gitlab-org/gitlab/-/issues/417433) | | [`create_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74632) | Event triggered when an external audit event destination is created| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/344664) | -| [`create_http_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136047) | Event triggered when a namespace filter for group level external audit event destination is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.6](https://gitlab.com/gitlab-org/gitlab/-/issues/424176) | +| [`create_http_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136047) | Event triggered when a namespace filter for an external audit event destination for a top-level group is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.6](https://gitlab.com/gitlab-org/gitlab/-/issues/424176) | | [`create_instance_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123882) | Event triggered when an instance level external audit event destination is created| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.2](https://gitlab.com/gitlab-org/gitlab/-/issues/404730) | | [`destroy_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74632) | Event triggered when an external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/344664) | | [`destroy_instance_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125846) | Event triggered when an instance level external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.2](https://gitlab.com/gitlab-org/gitlab/-/issues/404730) | diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index ed26bab8e126cf..14ca3565bc5df3 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -1573,9 +1573,9 @@ Input type: `AuditEventsStreamingHTTPNamespaceFiltersAddInput` | Name | Type | Description | | ---- | ---- | ----------- | | `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | -| `destinationId` | [`AuditEventsExternalAuditEventDestinationID!`](#auditeventsexternalauditeventdestinationid) | Destination id. | -| `groupPath` | [`ID`](#id) | Group full path. | -| `projectPath` | [`ID`](#id) | Project full path. | +| `destinationId` | [`AuditEventsExternalAuditEventDestinationID!`](#auditeventsexternalauditeventdestinationid) | Destination ID. | +| `groupPath` | [`ID`](#id) | Full path of the group. | +| `projectPath` | [`ID`](#id) | Full path of the project. | #### Fields -- GitLab From 834af7103c6e15488d51a6927556d176f5602278 Mon Sep 17 00:00:00 2001 From: Huzaifa Iftikhar Date: Fri, 10 Nov 2023 08:01:17 +0000 Subject: [PATCH 5/5] Adding suggestion for rspec --- .../streaming/http/namespace_filters/create_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb b/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb index aae350a17010e3..78b07c56fd905b 100644 --- a/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb +++ b/ee/spec/requests/api/graphql/audit_events/streaming/http/namespace_filters/create_spec.rb @@ -43,7 +43,7 @@ } end - it 'creates a namespace filter' do + it 'creates a namespace filter', :aggregate_failures do expect(::Gitlab::Audit::Auditor).to receive(:audit).with(a_hash_including( name: 'create_http_namespace_filter', author: current_user, -- GitLab