Commit 8155ccf4 authored by Vitali Tatarintev's avatar Vitali Tatarintev

Move custom mapping params to HttpIntegrationType

Move custom mapping params to HttpIntegrationType so IntegrationType
doesn't expose them
parent 6c105a39
# frozen_string_literal: true
module Resolvers
module AlertManagement
class HttpIntegrationsResolver < BaseResolver
alias_method :project, :synchronized_object
type Types::AlertManagement::HttpIntegrationType.connection_type, null: true
def resolve(**args)
http_integrations
end
private
def http_integrations
return [] unless Ability.allowed?(current_user, :admin_operations, project)
::AlertManagement::HttpIntegrationsFinder.new(project, {}).execute
end
end
end
end
......@@ -20,3 +20,5 @@ module Types
end
end
end
Types::AlertManagement::HttpIntegrationType.prepend_ee_mod
......@@ -56,5 +56,3 @@ module Types
end
end
end
Types::AlertManagement::IntegrationType.include_if_ee('::EE::Types::AlertManagement::IntegrationType')
......@@ -33,14 +33,6 @@ module Types
def active
prometheus_service.manual_configuration?
end
def payload_example
{}
end
def payload_attribute_mappings
[]
end
end
end
end
......@@ -273,6 +273,12 @@ module Types
description: 'Integrations which can receive alerts for the project.',
resolver: Resolvers::AlertManagement::IntegrationsResolver
field :alert_management_http_integrations,
Types::AlertManagement::HttpIntegrationType.connection_type,
null: true,
description: 'HTTP Integrations which can receive alerts for the project.',
resolver: Resolvers::AlertManagement::HttpIntegrationsResolver
field :releases,
Types::ReleaseType.connection_type,
null: true,
......
......@@ -660,6 +660,41 @@ type AlertManagementHttpIntegration implements AlertManagementIntegration {
url: String
}
"""
The connection type for AlertManagementHttpIntegration.
"""
type AlertManagementHttpIntegrationConnection {
"""
A list of edges.
"""
edges: [AlertManagementHttpIntegrationEdge]
"""
A list of nodes.
"""
nodes: [AlertManagementHttpIntegration]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type AlertManagementHttpIntegrationEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: AlertManagementHttpIntegration
}
"""
Identifier of AlertManagement::HttpIntegration.
"""
......@@ -686,16 +721,6 @@ interface AlertManagementIntegration {
"""
name: String
"""
The custom mapping of GitLab alert attributes to fields from the payload_example.
"""
payloadAttributeMappings: [AlertManagementPayloadAlertMappingField!]
"""
The example of an alert payload.
"""
payloadExample: JsonString
"""
Token used to authenticate alert notification requests.
"""
......@@ -931,16 +956,6 @@ type AlertManagementPrometheusIntegration implements AlertManagementIntegration
"""
name: String
"""
The custom mapping of GitLab alert attributes to fields from the payload_example.
"""
payloadAttributeMappings: [AlertManagementPayloadAlertMappingField!]
"""
The example of an alert payload.
"""
payloadExample: JsonString
"""
Token used to authenticate alert notification requests.
"""
......@@ -19086,6 +19101,31 @@ type Project {
statuses: [AlertManagementStatus!]
): AlertManagementAlertConnection
"""
HTTP Integrations which can receive alerts for the project.
"""
alertManagementHttpIntegrations(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): AlertManagementHttpIntegrationConnection
"""
Integrations which can receive alerts for the project.
"""
......
......@@ -1672,6 +1672,118 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "AlertManagementHttpIntegrationConnection",
"description": "The connection type for AlertManagementHttpIntegration.",
"fields": [
{
"name": "edges",
"description": "A list of edges.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AlertManagementHttpIntegrationEdge",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "nodes",
"description": "A list of nodes.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AlertManagementHttpIntegration",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "pageInfo",
"description": "Information to aid in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "PageInfo",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "AlertManagementHttpIntegrationEdge",
"description": "An edge in a connection.",
"fields": [
{
"name": "cursor",
"description": "A cursor for use in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "node",
"description": "The item at the end of the edge.",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "AlertManagementHttpIntegration",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "AlertManagementHttpIntegrationID",
......@@ -1747,42 +1859,6 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "payloadAttributeMappings",
"description": "The custom mapping of GitLab alert attributes to fields from the payload_example.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AlertManagementPayloadAlertMappingField",
"ofType": null
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "payloadExample",
"description": "The example of an alert payload.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "JsonString",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "token",
"description": "Token used to authenticate alert notification requests.",
......@@ -2357,42 +2433,6 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "payloadAttributeMappings",
"description": "The custom mapping of GitLab alert attributes to fields from the payload_example.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AlertManagementPayloadAlertMappingField",
"ofType": null
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "payloadExample",
"description": "The example of an alert payload.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "JsonString",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "token",
"description": "Token used to authenticate alert notification requests.",
......@@ -56049,6 +56089,59 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "alertManagementHttpIntegrations",
"description": "HTTP Integrations which can receive alerts for the project.",
"args": [
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "before",
"description": "Returns the elements in the list that come before the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": "Returns the first _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "last",
"description": "Returns the last _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "AlertManagementHttpIntegrationConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "alertManagementIntegrations",
"description": "Integrations which can receive alerts for the project.",
......@@ -311,8 +311,6 @@ An endpoint and credentials used to accept Prometheus alerts for a project.
| `apiUrl` | String | URL at which Prometheus metrics can be queried to populate the metrics dashboard. |
| `id` | ID! | ID of the integration. |
| `name` | String | Name of the integration. |
| `payloadAttributeMappings` | AlertManagementPayloadAlertMappingField! => Array | The custom mapping of GitLab alert attributes to fields from the payload_example. |
| `payloadExample` | JsonString | The example of an alert payload. |
| `token` | String | Token used to authenticate alert notification requests. |
| `type` | AlertManagementIntegrationType! | Type of integration. |
| `url` | String | Endpoint which accepts alert notifications. |
......@@ -3043,6 +3041,7 @@ Autogenerated return type of PipelineRetry.
| `alertManagementAlert` | AlertManagementAlert | A single Alert Management alert of the project. |
| `alertManagementAlertStatusCounts` | AlertManagementAlertStatusCountsType | Counts of alerts by status for the project. |
| `alertManagementAlerts` | AlertManagementAlertConnection | Alert Management alerts of the project. |
| `alertManagementHttpIntegrations` | AlertManagementHttpIntegrationConnection | HTTP Integrations which can receive alerts for the project. |
| `alertManagementIntegrations` | AlertManagementIntegrationConnection | Integrations which can receive alerts for the project. |
| `alertManagementPayloadFields` | AlertManagementPayloadAlertField! => Array | Extract alert fields from payload for custom mapping. |
| `allowMergeOnSkippedPipeline` | Boolean | If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge requests of the project can also be merged with skipped jobs. |
......
......@@ -3,10 +3,10 @@
module EE
module Types
module AlertManagement
module IntegrationType
module HttpIntegrationType
extend ActiveSupport::Concern
included do
prepended do
field :payload_example, ::Types::JsonStringType,
null: true,
description: 'The example of an alert payload.'
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['AlertManagementHttpIntegration'] do
specify { expect(described_class.graphql_name).to eq('AlertManagementHttpIntegration') }
specify { expect(described_class).to require_graphql_authorizations(:admin_operations) }
it 'exposes the expected fields' do
expected_fields = %i[
id
type
name
active
token
url
api_url
payload_example
payload_attribute_mappings
]
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'getting Alert Management HTTP Integrations' do
include ::Gitlab::Routing.url_helpers
include GraphqlHelpers
let_it_be(:payload_example) do
{
alert: {
desc: 'Alert description',
name: 'Alert name'
}
}
end
let_it_be(:payload_attribute_mapping) do
{
title: { path: %w(alert name), type: 'string' },
description: { path: %w(alert desc), type: 'string', label: 'Description' }
}
end
let_it_be(:project) { create(:project, :repository) }
let_it_be(:current_user) { create(:user) }
let_it_be(:prometheus_service) { create(:prometheus_service, project: project) }
let_it_be(:project_alerting_setting) { create(:project_alerting_setting, project: project) }
let_it_be(:inactive_http_integration) { create(:alert_management_http_integration, :inactive, project: project) }
let_it_be(:other_project_http_integration) { create(:alert_management_http_integration) }
let_it_be(:active_http_integration) do
create(
:alert_management_http_integration,
project: project,
payload_example: payload_example,
payload_attribute_mapping: payload_attribute_mapping
)
end
let(:fields) do
<<~QUERY
nodes {
#{all_graphql_fields_for('AlertManagementHttpIntegration')}
}
QUERY
end
let(:query) do
graphql_query_for(
'project',
{ 'fullPath' => project.full_path },
query_graphql_field('alertManagementHttpIntegrations', {}, fields)
)
end
before do
stub_licensed_features(multiple_alert_http_integrations: true)
stub_feature_flags(multiple_http_integrations_custom_mapping: project)
end
context 'with integrations' do
let(:integrations) { graphql_data.dig('project', 'alertManagementHttpIntegrations', 'nodes') }
context 'without project permissions' do
let(:user) { create(:user) }
before do
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
specify { expect(integrations).to be_nil }
end
context 'with project permissions' do
before do
project.add_maintainer(current_user)
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
specify { expect(integrations.size).to eq(2) }
it 'returns the correct properties of the integrations' do
expect(integrations).to include(
{
'id' => GitlabSchema.id_from_object(active_http_integration).to_s,
'type' => 'HTTP',
'name' => active_http_integration.name,
'active' => active_http_integration.active,
'token' => active_http_integration.token,
'url' => active_http_integration.url,
'apiUrl' => nil,
'payloadExample' => payload_example.to_json,
'payloadAttributeMappings' => [
{
'fieldName' => 'TITLE',
'label' => nil,
'path' => %w(alert name),
'type' => 'STRING'
},
{
'fieldName' => 'DESCRIPTION',
'label' => 'Description',
'path' => %w(alert desc),
'type' => 'STRING'
}
]
},
{
'id' => GitlabSchema.id_from_object(inactive_http_integration).to_s,
'type' => 'HTTP',
'name' => inactive_http_integration.name,
'active' => inactive_http_integration.active,
'token' => inactive_http_integration.token,
'url' => inactive_http_integration.url,
'apiUrl' => nil,
'payloadExample' => "{}",
'payloadAttributeMappings' => []
}
)
end
end
end
end
......@@ -5,36 +5,13 @@ RSpec.describe 'getting Alert Management Integrations' do
include ::Gitlab::Routing.url_helpers
include GraphqlHelpers
let_it_be(:payload_example) do
{
alert: {
desc: 'Alert description',
name: 'Alert name'
}
}
end
let_it_be(:payload_attribute_mapping) do
{
title: { path: %w(alert name), type: 'string' },
description: { path: %w(alert desc), type: 'string', label: 'Description' }
}
end
let_it_be(:project) { create(:project, :repository) }
let_it_be(:current_user) { create(:user) }
let_it_be(:prometheus_service) { create(:prometheus_service, project: project) }
let_it_be(:project_alerting_setting) { create(:project_alerting_setting, project: project) }
let_it_be(:active_http_integration) { create(:alert_management_http_integration, project: project) }
let_it_be(:inactive_http_integration) { create(:alert_management_http_integration, :inactive, project: project) }
let_it_be(:project_alerting_setting) { create(:project_alerting_setting, project: project) }
let_it_be(:other_project_http_integration) { create(:alert_management_http_integration) }
let_it_be(:active_http_integration) do
create(
:alert_management_http_integration,
project: project,
payload_example: payload_example,
payload_attribute_mapping: payload_attribute_mapping
)
end
let(:fields) do
<<~QUERY
......@@ -54,7 +31,6 @@ RSpec.describe 'getting Alert Management Integrations' do
before do
stub_licensed_features(multiple_alert_http_integrations: true)
stub_feature_flags(multiple_http_integrations_custom_mapping: project)
end
context 'with integrations' do
......@@ -91,22 +67,7 @@ RSpec.describe 'getting Alert Management Integrations' do
'active' => active_http_integration.active,
'token' => active_http_integration.token,
'url' => active_http_integration.url,
'apiUrl' => nil,
'payloadExample' => payload_example.to_json,
'payloadAttributeMappings' => [
{
'fieldName' => 'TITLE',
'label' => nil,
'path' => %w(alert name),
'type' => 'STRING'
},
{
'fieldName' => 'DESCRIPTION',
'label' => 'Description',
'path' => %w(alert desc),
'type' => 'STRING'
}
]
'apiUrl' => nil
},
{
'id' => GitlabSchema.id_from_object(inactive_http_integration).to_s,
......@@ -115,9 +76,7 @@ RSpec.describe 'getting Alert Management Integrations' do
'active' => inactive_http_integration.active,
'token' => inactive_http_integration.token,
'url' => inactive_http_integration.url,
'apiUrl' => nil,
'payloadExample' => "{}",
'payloadAttributeMappings' => []
'apiUrl' => nil
},
{
'id' => GitlabSchema.id_from_object(prometheus_service).to_s,
......@@ -126,9 +85,7 @@ RSpec.describe 'getting Alert Management Integrations' do
'active' => prometheus_service.manual_configuration?,
'token' => project_alerting_setting.token,
'url' => "http://localhost/#{project.full_path}/prometheus/alerts/notify.json",
'apiUrl' => prometheus_service.api_url,
'payloadExample' => "{}",
'payloadAttributeMappings' => []
'apiUrl' => prometheus_service.api_url
}
)
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Resolvers::AlertManagement::HttpIntegrationsResolver do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:prometheus_integration) { create(:prometheus_service, project: project) }
let_it_be(:active_http_integration) { create(:alert_management_http_integration, project: project) }
let_it_be(:inactive_http_integration) { create(:alert_management_http_integration, :inactive, project: project) }
let_it_be(:other_proj_integration) { create(:alert_management_http_integration) }
subject { sync(resolve_http_integrations) }
specify do
expect(described_class).to have_nullable_graphql_type(Types::AlertManagement::HttpIntegrationType.connection_type)
end
context 'user does not have permission' do
it { is_expected.to be_empty }
end
context 'user has permission' do
before do
project.add_maintainer(current_user)
end
it { is_expected.to contain_exactly(active_http_integration) }
end
private
def resolve_http_integrations(args = {}, context = { current_user: current_user })
resolve(described_class, obj: project, ctx: context)
end
end
......@@ -16,10 +16,6 @@ RSpec.describe GitlabSchema.types['AlertManagementIntegration'] do
api_url
]
if Gitlab.ee?
expected_fields.push('payload_example', 'payload_attribute_mappings')
end
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment