From e0b783c23ae5660cc4b4cb1a4b2999fc4f539eee Mon Sep 17 00:00:00 2001 From: nrosandich Date: Wed, 5 Jul 2023 09:17:12 +1200 Subject: [PATCH 1/3] Add gcp logging streaming destination Adds a form to manage streaming audit event destination integration with GCP Logging. Changelog: changed EE: true --- .../components/audit_events_stream.vue | 152 +++++++- .../components/stream/stream_delete_modal.vue | 45 ++- .../stream/stream_destination_editor.vue | 3 + .../components/stream/stream_empty_state.vue | 49 ++- .../stream_gcp_logging_destination_editor.vue | 297 ++++++++++++++++ .../components/stream/stream_item.vue | 38 +- .../javascripts/audit_events/constants.js | 14 + .../audit_events/graphql/cache_update.js | 42 +++ ...e_gcp_logging_destination.mutation.graphql | 26 ++ ...e_gcp_logging_destination.mutation.graphql | 5 + ...e_gcp_logging_destination.mutation.graphql | 26 ++ ...e_cloud_logging_destinations.query.graphql | 14 + .../components/audit_events_stream_spec.js | 103 ++++-- .../stream_empty_state_spec.js.snap | 16 +- .../__snapshots__/stream_item_spec.js.snap | 2 +- .../stream/stream_delete_modal_spec.js | 65 +++- .../stream/stream_destination_editor_spec.js | 2 +- .../stream/stream_empty_state_spec.js | 14 +- ...eam_gcp_logging_destination_editor_spec.js | 325 ++++++++++++++++++ .../components/stream/stream_item_spec.js | 79 ++++- ee/spec/frontend/audit_events/mock_data.js | 82 ++++- locale/gitlab.pot | 27 ++ 22 files changed, 1330 insertions(+), 96 deletions(-) create mode 100644 ee/app/assets/javascripts/audit_events/components/stream/stream_gcp_logging_destination_editor.vue create mode 100644 ee/app/assets/javascripts/audit_events/graphql/mutations/create_gcp_logging_destination.mutation.graphql create mode 100644 ee/app/assets/javascripts/audit_events/graphql/mutations/delete_gcp_logging_destination.mutation.graphql create mode 100644 ee/app/assets/javascripts/audit_events/graphql/mutations/update_gcp_logging_destination.mutation.graphql create mode 100644 ee/app/assets/javascripts/audit_events/graphql/queries/get_get_google_cloud_logging_destinations.query.graphql create mode 100644 ee/spec/frontend/audit_events/components/stream/stream_gcp_logging_destination_editor_spec.js diff --git a/ee/app/assets/javascripts/audit_events/components/audit_events_stream.vue b/ee/app/assets/javascripts/audit_events/components/audit_events_stream.vue index 471504f3ff83a6..a1df9728851324 100644 --- a/ee/app/assets/javascripts/audit_events/components/audit_events_stream.vue +++ b/ee/app/assets/javascripts/audit_events/components/audit_events_stream.vue @@ -1,28 +1,38 @@ diff --git a/ee/app/assets/javascripts/audit_events/components/stream/stream_delete_modal.vue b/ee/app/assets/javascripts/audit_events/components/stream/stream_delete_modal.vue index 0e858416881b4c..be0747356a39e2 100644 --- a/ee/app/assets/javascripts/audit_events/components/stream/stream_delete_modal.vue +++ b/ee/app/assets/javascripts/audit_events/components/stream/stream_delete_modal.vue @@ -2,10 +2,10 @@ import { GlModal, GlSprintf } from '@gitlab/ui'; import { __, s__ } from '~/locale'; -import externalDestinationsQuery from '../../graphql/queries/get_external_destinations.query.graphql'; -import instanceExternalDestinationsQuery from '../../graphql/queries/get_instance_external_destinations.query.graphql'; import deleteExternalDestination from '../../graphql/mutations/delete_external_destination.mutation.graphql'; import deleteInstanceExternalDestination from '../../graphql/mutations/delete_instance_external_destination.mutation.graphql'; +import googleCloudLoggingConfigurationDestroy from '../../graphql/mutations/delete_gcp_logging_destination.mutation.graphql'; +import { DESTINATION_TYPE_HTTP, DESTINATION_TYPE_GCP_LOGGING } from '../../constants'; export default { components: { @@ -18,19 +18,46 @@ export default { type: Object, required: true, }, + type: { + type: String, + required: true, + }, }, computed: { isInstance() { return this.groupPath === 'instance'; }, - destinationQuery() { - return this.isInstance ? instanceExternalDestinationsQuery : externalDestinationsQuery; - }, destinationDestroyMutation() { - return this.isInstance ? deleteInstanceExternalDestination : deleteExternalDestination; + switch (this.type) { + case DESTINATION_TYPE_GCP_LOGGING: + return googleCloudLoggingConfigurationDestroy; + case DESTINATION_TYPE_HTTP: + default: + return this.isInstance ? deleteInstanceExternalDestination : deleteExternalDestination; + } + }, + destinationTitle() { + switch (this.type) { + case DESTINATION_TYPE_GCP_LOGGING: + return this.item.googleProjectIdName; + case DESTINATION_TYPE_HTTP: + default: + return this.item.destinationUrl; + } }, }, methods: { + destinationErrors(data) { + switch (this.type) { + case DESTINATION_TYPE_GCP_LOGGING: + return data.googleCloudLoggingConfigurationDestroy.errors; + case DESTINATION_TYPE_HTTP: + default: + return this.isInstance + ? data.instanceExternalAuditEventDestinationDestroy.errors + : data.externalAuditEventDestinationDestroy.errors; + } + }, async deleteDestination() { this.reportDeleting(); @@ -46,9 +73,7 @@ export default { }, }); - const errors = this.isInstance - ? data.instanceExternalAuditEventDestinationDestroy.errors - : data.externalAuditEventDestinationDestroy.errors; + const errors = this.destinationErrors(data); if (errors.length > 0) { this.reportError(new Error(errors[0])); @@ -100,7 +125,7 @@ export default { > diff --git a/ee/app/assets/javascripts/audit_events/components/stream/stream_destination_editor.vue b/ee/app/assets/javascripts/audit_events/components/stream/stream_destination_editor.vue index 1136b442bf6485..bf46de11714450 100644 --- a/ee/app/assets/javascripts/audit_events/components/stream/stream_destination_editor.vue +++ b/ee/app/assets/javascripts/audit_events/components/stream/stream_destination_editor.vue @@ -32,6 +32,7 @@ import { ADD_STREAM_EDITOR_I18N, AUDIT_STREAMS_NETWORK_ERRORS, createBlankHeader, + DESTINATION_TYPE_HTTP, } from '../../constants'; import { addAuditEventsStreamingDestination, @@ -596,6 +597,7 @@ export default { tdClass: finalTdClasses, }, ], + DESTINATION_TYPE_HTTP, }; @@ -799,6 +801,7 @@ export default { -import { GlButton, GlEmptyState } from '@gitlab/ui'; -import { ADD_STREAM, AUDIT_STREAMS_EMPTY_STATE_I18N } from '../../constants'; +import { GlEmptyState, GlDisclosureDropdown } from '@gitlab/ui'; +import { + ADD_STREAM, + AUDIT_STREAMS_EMPTY_STATE_I18N, + ADD_HTTP, + ADD_GCP_LOGGING, +} from '../../constants'; export default { components: { - GlButton, GlEmptyState, + GlDisclosureDropdown, + }, + inject: ['groupPath', 'emptyStateSvgPath'], + data() { + return { + items: [ + { + text: ADD_HTTP, + action: () => { + this.$emit('addHttp'); + }, + }, + { + text: ADD_GCP_LOGGING, + action: () => { + this.$emit('addGcpLogging'); + }, + }, + ], + }; + }, + computed: { + isInstance() { + return this.groupPath === 'instance'; + }, + addOptions() { + return this.isInstance ? [this.items[0]] : this.items; + }, }, - inject: ['emptyStateSvgPath'], i18n: { ...AUDIT_STREAMS_EMPTY_STATE_I18N, ADD_STREAM, @@ -32,9 +63,13 @@ export default {

{{ $options.i18n.DESCRIPTION_2 }}

diff --git a/ee/app/assets/javascripts/audit_events/components/stream/stream_gcp_logging_destination_editor.vue b/ee/app/assets/javascripts/audit_events/components/stream/stream_gcp_logging_destination_editor.vue new file mode 100644 index 00000000000000..b31084fa9b275a --- /dev/null +++ b/ee/app/assets/javascripts/audit_events/components/stream/stream_gcp_logging_destination_editor.vue @@ -0,0 +1,297 @@ + + + diff --git a/ee/app/assets/javascripts/audit_events/components/stream/stream_item.vue b/ee/app/assets/javascripts/audit_events/components/stream/stream_item.vue index 3bfb27cfb8ef29..9be778e430cfc7 100644 --- a/ee/app/assets/javascripts/audit_events/components/stream/stream_item.vue +++ b/ee/app/assets/javascripts/audit_events/components/stream/stream_item.vue @@ -9,8 +9,13 @@ import { GlButton, GlTooltipDirective as GlTooltip, } from '@gitlab/ui'; -import { STREAM_ITEMS_I18N } from '../../constants'; +import { + STREAM_ITEMS_I18N, + DESTINATION_TYPE_HTTP, + DESTINATION_TYPE_GCP_LOGGING, +} from '../../constants'; import StreamDestinationEditor from './stream_destination_editor.vue'; +import StreamGcpLoggingDestinationEditor from './stream_gcp_logging_destination_editor.vue'; export default { components: { @@ -22,6 +27,7 @@ export default { GlButton, GlIcon, StreamDestinationEditor, + StreamGcpLoggingDestinationEditor, }, directives: { GlTooltip, @@ -32,6 +38,10 @@ export default { type: Object, required: true, }, + type: { + type: String, + required: true, + }, }, data() { return { @@ -45,6 +55,15 @@ export default { isInstance() { return this.groupPath === 'instance'; }, + destinationTitle() { + switch (this.type) { + case DESTINATION_TYPE_GCP_LOGGING: + return this.item.googleProjectIdName; + case DESTINATION_TYPE_HTTP: + default: + return this.item.destinationUrl; + } + }, }, methods: { toggleEditMode() { @@ -66,7 +85,9 @@ export default { : queryData.group.externalAuditEventDestinationCreate; }, }, - i18n: STREAM_ITEMS_I18N, + i18n: { ...STREAM_ITEMS_I18N }, + DESTINATION_TYPE_HTTP, + DESTINATION_TYPE_GCP_LOGGING, }; @@ -84,7 +105,7 @@ export default { name="chevron-right" class="gl-transition-medium" :class="{ 'gl-rotate-90': isEditing }" - />{{ item.destinationUrl }} + />{{ destinationTitle }}