Commit 63e1db26 authored by Andy Soiron's avatar Andy Soiron

Merge branch '334500-mount-rest-endpoints-as-integrations-endpoints' into 'master'

Mount services REST endpoints as integrations endpoints

See merge request gitlab-org/gitlab!71216
parents 0fdee391 0398c12b
......@@ -42,6 +42,7 @@ The following API resources are available in the project context:
| [Events](events.md) | `/projects/:id/events` (also available for users and standalone) |
| [Feature Flags](feature_flags.md) | `/projects/:id/feature_flags` |
| [Feature Flag User Lists](feature_flag_user_lists.md) | `/projects/:id/feature_flags_user_lists` |
| [Integrations](integrations.md) | `/projects/:id/integrations` |
| [Invitations](invitations.md) | `/projects/:id/invitations` (also available for groups) |
| [Issues](issues.md) | `/projects/:id/issues` (also available for groups and standalone) |
| [Issues Statistics](issues_statistics.md) | `/projects/:id/issues_statistics` (also available for groups and standalone) |
......@@ -82,7 +83,7 @@ The following API resources are available in the project context:
| [Resource label events](resource_label_events.md) | `/projects/:id/issues/.../resource_label_events`, `/projects/:id/merge_requests/.../resource_label_events` (also available for groups) |
| [Runners](runners.md) | `/projects/:id/runners` (also available standalone) |
| [Search](search.md) | `/projects/:id/search` (also available for groups and standalone) |
| [Services](services.md) | `/projects/:id/services` |
| [Services](services.md) (renamed to [Integrations](integrations.md)) | `/projects/:id/services` |
| [Tags](tags.md) | `/projects/:id/repository/tags` |
| [User-starred metrics dashboards](metrics_user_starred_dashboards.md ) | `/projects/:id/metrics/user_starred_dashboards` |
| [Visual Review discussions](visual_review_discussions.md) **(PREMIUM)** | `/projects/:id/merge_requests/:merge_request_id/visual_review_discussions` |
......
This diff is collapsed.
This diff is collapsed.
......@@ -4,9 +4,9 @@ group: Integrations
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Asana service **(FREE)**
# Asana integration **(FREE)**
This service adds commit messages as comments to Asana tasks.
This integration adds commit messages as comments to Asana tasks.
Once enabled, commit messages are checked for Asana task URLs (for example,
`https://app.asana.com/0/123456/987654`) or task IDs starting with `#`
(for example, `#987654`). Every task ID found gets the commit comment added to it.
......@@ -23,7 +23,7 @@ You can use either of these words:
- `closed`
- `closing`
See also the [Asana service API documentation](../../../api/services.md#asana).
See also the [Asana integration API documentation](../../../api/integrations.md#asana).
## Setup
......
......@@ -32,7 +32,7 @@ Click on the service links to see further configuration instructions and details
| [Bugzilla](bugzilla.md) | Use Bugzilla as the issue tracker. | **{dotted-circle}** No |
| Buildkite | Run CI/CD pipelines with Buildkite. | **{check-circle}** Yes |
| Campfire | Connect to chat. | **{dotted-circle}** No |
| [Confluence Workspace](../../../api/services.md#confluence-service) | Replace the link to the internal wiki with a link to a Confluence Cloud Workspace. | **{dotted-circle}** No |
| [Confluence Workspace](../../../api/integrations.md#confluence-integration) | Replace the link to the internal wiki with a link to a Confluence Cloud Workspace. | **{dotted-circle}** No |
| [Custom issue tracker](custom_issue_tracker.md) | Use a custom issue tracker. | **{dotted-circle}** No |
| [Datadog](../../../integration/datadog.md) | Trace your GitLab pipelines with Datadog. | **{check-circle}** Yes |
| [Discord Notifications](discord_notifications.md) | Send notifications about project events to a Discord channel. | **{dotted-circle}** No |
......@@ -40,7 +40,7 @@ Click on the service links to see further configuration instructions and details
| [Emails on push](emails_on_push.md) | Send commits and diff of each push by email. | **{dotted-circle}** No |
| [EWM](ewm.md) | Use IBM Engineering Workflow Management as the issue tracker. | **{dotted-circle}** No |
| [External wiki](../wiki/index.md#link-an-external-wiki) | Link an external wiki. | **{dotted-circle}** No |
| [Flowdock](../../../api/services.md#flowdock) | Send notifications from GitLab to Flowdock flows. | **{dotted-circle}** No |
| [Flowdock](../../../api/integrations.md#flowdock) | Send notifications from GitLab to Flowdock flows. | **{dotted-circle}** No |
| [GitHub](github.md) | Obtain statuses for commits and pull requests. | **{dotted-circle}** No |
| [Google Chat](hangouts_chat.md) | Send notifications from your GitLab project to a room in Google Chat.| **{dotted-circle}** No |
| [irker (IRC gateway)](irker.md) | Send IRC messages. | **{dotted-circle}** No |
......
......@@ -29,7 +29,7 @@ Read more about the
[Source Commits endpoint](https://www.pivotaltracker.com/help/api/rest/v5#Source_Commits) in
the Pivotal Tracker API documentation.
See also the [Pivotal Tracker service API documentation](../../../api/services.md#pivotal-tracker).
See also the [Pivotal Tracker integration API documentation](../../../api/integrations.md#pivotal-tracker).
## Set up Pivotal Tracker
......
......@@ -28,7 +28,7 @@ module EE
{
required: false,
name: :static_context,
type: ::API::Services::Boolean,
type: ::API::Integrations::Boolean,
desc: 'Append instance name instead of branch to status check name'
}
]
......@@ -63,7 +63,7 @@ module EE
{
required: false,
name: :vulnerability_events,
type: ::API::Services::Boolean,
type: ::API::Integrations::Boolean,
desc: 'Enable notifications for vulnerability_events'
}
].freeze
......
......@@ -2,7 +2,7 @@
module EE
module API
module Services
module Integrations
extend ActiveSupport::Concern
prepended do
......
......@@ -2,7 +2,7 @@
require "spec_helper"
RSpec.describe API::Services do
RSpec.describe API::Integrations do
let_it_be(:user) { create(:user) }
let_it_be(:project) do
......
......@@ -260,7 +260,7 @@ module API
mount ::API::ResourceAccessTokens
mount ::API::RubygemPackages
mount ::API::Search
mount ::API::Services
mount ::API::Integrations
mount ::API::Settings
mount ::API::SidekiqMetrics
mount ::API::SnippetRepositoryStorageMoves
......
......@@ -2,7 +2,7 @@
module API
module Helpers
# Helpers module for API::Services
# Helpers module for API::Integrations
#
# The data structures inside this model are returned using class methods,
# allowing EE to extend them where necessary.
......
# frozen_string_literal: true
module API
class Services < ::API::Base
class Integrations < ::API::Base
feature_category :integrations
integrations = Helpers::IntegrationsHelpers.integrations
......@@ -12,7 +12,7 @@ module API
required: true,
name: :mock_service_url,
type: String,
desc: 'URL to the mock service'
desc: 'URL to the mock integration'
}
]
integrations['mock-deployment'] = []
......@@ -52,117 +52,122 @@ module API
]
}.freeze
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before { authenticate! }
before { authorize_admin_project }
helpers do
def integration_attributes(integration)
integration.fields.inject([]) do |arr, hash|
arr << hash[:name].to_sym
end
helpers do
def integration_attributes(integration)
integration.fields.inject([]) do |arr, hash|
arr << hash[:name].to_sym
end
end
end
desc 'Get all active project integrations' do
success Entities::ProjectIntegrationBasic
# The API officially documents only the `:id/integrations` API paths.
# We support the older `id:/services` path for backwards-compatibility in API V4.
# The support for `:id/services` can be dropped if we create an API V5.
[':id/services', ':id/integrations'].each do |path|
params do
requires :id, type: String, desc: 'The ID of a project'
end
get ":id/services" do
integrations = user_project.integrations.active
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before { authenticate! }
before { authorize_admin_project }
present integrations, with: Entities::ProjectIntegrationBasic
end
desc 'Get all active project integrations' do
success Entities::ProjectIntegrationBasic
end
get path do
integrations = user_project.integrations.active
INTEGRATIONS.each do |slug, settings|
desc "Set #{slug} integration for project"
params do
settings.each do |setting|
if setting[:required]
requires setting[:name], type: setting[:type], desc: setting[:desc]
else
optional setting[:name], type: setting[:type], desc: setting[:desc]
present integrations, with: Entities::ProjectIntegrationBasic
end
INTEGRATIONS.each do |slug, settings|
desc "Set #{slug} integration for project"
params do
settings.each do |setting|
if setting[:required]
requires setting[:name], type: setting[:type], desc: setting[:desc]
else
optional setting[:name], type: setting[:type], desc: setting[:desc]
end
end
end
end
put ":id/services/#{slug}" do
integration = user_project.find_or_initialize_integration(slug.underscore)
params = declared_params(include_missing: false).merge(active: true)
if integration.update(params)
present integration, with: Entities::ProjectIntegration
else
render_api_error!('400 Bad Request', 400)
put "#{path}/#{slug}" do
integration = user_project.find_or_initialize_integration(slug.underscore)
params = declared_params(include_missing: false).merge(active: true)
if integration.update(params)
present integration, with: Entities::ProjectIntegration
else
render_api_error!('400 Bad Request', 400)
end
end
end
end
desc "Delete an integration from a project"
params do
requires :slug, type: String, values: INTEGRATIONS.keys, desc: 'The name of the service'
end
delete ":id/services/:slug" do
integration = user_project.find_or_initialize_integration(params[:slug].underscore)
desc "Delete an integration from a project"
params do
requires :slug, type: String, values: INTEGRATIONS.keys, desc: 'The name of the integration'
end
delete "#{path}/:slug" do
integration = user_project.find_or_initialize_integration(params[:slug].underscore)
destroy_conditionally!(integration) do
attrs = integration_attributes(integration).index_with { nil }.merge(active: false)
destroy_conditionally!(integration) do
attrs = integration_attributes(integration).index_with { nil }.merge(active: false)
render_api_error!('400 Bad Request', 400) unless integration.update(attrs)
render_api_error!('400 Bad Request', 400) unless integration.update(attrs)
end
end
end
desc 'Get the integration settings for a project' do
success Entities::ProjectIntegration
end
params do
requires :slug, type: String, values: INTEGRATIONS.keys, desc: 'The name of the service'
end
get ":id/services/:slug" do
integration = user_project.find_or_initialize_integration(params[:slug].underscore)
desc 'Get the integration settings for a project' do
success Entities::ProjectIntegration
end
params do
requires :slug, type: String, values: INTEGRATIONS.keys, desc: 'The name of the integration'
end
get "#{path}/:slug" do
integration = user_project.find_or_initialize_integration(params[:slug].underscore)
not_found!('Service') unless integration&.persisted?
not_found!('Integration') unless integration&.persisted?
present integration, with: Entities::ProjectIntegration
present integration, with: Entities::ProjectIntegration
end
end
end
TRIGGER_INTEGRATIONS.each do |integration_slug, settings|
helpers do
def slash_command_integration(project, integration_slug, params)
project.integrations.active.find do |integration|
integration.try(:token) == params[:token] && integration.to_param == integration_slug.underscore
TRIGGER_INTEGRATIONS.each do |integration_slug, settings|
helpers do
def slash_command_integration(project, integration_slug, params)
project.integrations.active.find do |integration|
integration.try(:token) == params[:token] && integration.to_param == integration_slug.underscore
end
end
end
end
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc "Trigger a slash command for #{integration_slug}" do
detail 'Added in GitLab 8.13'
end
params do
settings.each do |setting|
requires setting[:name], type: setting[:type], desc: setting[:desc]
end
requires :id, type: String, desc: 'The ID of a project'
end
post ":id/services/#{integration_slug.underscore}/trigger" do
project = find_project(params[:id])
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc "Trigger a slash command for #{integration_slug}" do
detail 'Added in GitLab 8.13'
end
params do
settings.each do |setting|
requires setting[:name], type: setting[:type], desc: setting[:desc]
end
end
post "#{path}/#{integration_slug.underscore}/trigger" do
project = find_project(params[:id])
# This is not accurate, but done to prevent leakage of the project names
not_found!('Service') unless project
# This is not accurate, but done to prevent leakage of the project names
not_found!('Integration') unless project
integration = slash_command_integration(project, integration_slug, params)
result = integration.try(:trigger, params)
integration = slash_command_integration(project, integration_slug, params)
result = integration.try(:trigger, params)
if result
status result[:status] || 200
present result
else
not_found!('Service')
if result
status result[:status] || 200
present result
else
not_found!('Integration')
end
end
end
end
......@@ -170,4 +175,4 @@ module API
end
end
API::Services.prepend_mod_with('API::Services')
API::Integrations.prepend_mod_with('API::Integrations')
......@@ -30,7 +30,7 @@ module Gitlab
# Returns a class which inherits from the BaseService
# class that can be used to obtain a dashboard for
# the provided params.
# @return [Gitlab::Metrics::Dashboard::Services::BaseService]
# @return [Metrics::Dashboard::BaseService]
def call(params)
service = services.find do |service_class|
service_class.valid_params?(params)
......
{
"type": "array",
"items": { "$ref": "service.json" }
"items": { "$ref": "integration.json" }
}
This diff is collapsed.
This diff is collapsed.
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