Commit 2b6f1126 authored by Sean McGivern's avatar Sean McGivern

Merge branch '201848-rename-Service-model-to-Integration' into 'master'

Rename Service model to Integration [RUN ALL RSPEC] [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!61210
parents f4a6e822 682702b0
...@@ -200,7 +200,6 @@ Rails/SaveBang: ...@@ -200,7 +200,6 @@ Rails/SaveBang:
- 'spec/models/resource_milestone_event_spec.rb' - 'spec/models/resource_milestone_event_spec.rb'
- 'spec/models/route_spec.rb' - 'spec/models/route_spec.rb'
- 'spec/models/sentry_issue_spec.rb' - 'spec/models/sentry_issue_spec.rb'
- 'spec/models/service_spec.rb'
- 'spec/models/snippet_spec.rb' - 'spec/models/snippet_spec.rb'
- 'spec/models/upload_spec.rb' - 'spec/models/upload_spec.rb'
...@@ -566,7 +565,6 @@ RSpec/EmptyLineAfterFinalLetItBe: ...@@ -566,7 +565,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
- spec/models/prometheus_alert_spec.rb - spec/models/prometheus_alert_spec.rb
- spec/models/protected_branch/push_access_level_spec.rb - spec/models/protected_branch/push_access_level_spec.rb
- spec/models/repository_spec.rb - spec/models/repository_spec.rb
- spec/models/service_spec.rb
- spec/models/snippet_repository_spec.rb - spec/models/snippet_repository_spec.rb
- spec/models/snippet_spec.rb - spec/models/snippet_spec.rb
- spec/models/terraform/state_spec.rb - spec/models/terraform/state_spec.rb
...@@ -1586,6 +1584,7 @@ Gitlab/NamespacedClass: ...@@ -1586,6 +1584,7 @@ Gitlab/NamespacedClass:
- 'app/models/individual_note_discussion.rb' - 'app/models/individual_note_discussion.rb'
- 'app/models/instance_configuration.rb' - 'app/models/instance_configuration.rb'
- 'app/models/instance_metadata.rb' - 'app/models/instance_metadata.rb'
- 'app/models/integration.rb'
- 'app/models/internal_id.rb' - 'app/models/internal_id.rb'
- 'app/models/issuable_severity.rb' - 'app/models/issuable_severity.rb'
- 'app/models/issue.rb' - 'app/models/issue.rb'
...@@ -1751,7 +1750,6 @@ Gitlab/NamespacedClass: ...@@ -1751,7 +1750,6 @@ Gitlab/NamespacedClass:
- 'app/models/self_managed_prometheus_alert_event.rb' - 'app/models/self_managed_prometheus_alert_event.rb'
- 'app/models/sent_notification.rb' - 'app/models/sent_notification.rb'
- 'app/models/sentry_issue.rb' - 'app/models/sentry_issue.rb'
- 'app/models/service.rb'
- 'app/models/service_desk_setting.rb' - 'app/models/service_desk_setting.rb'
- 'app/models/service_list.rb' - 'app/models/service_list.rb'
- 'app/models/shard.rb' - 'app/models/shard.rb'
...@@ -1829,6 +1827,7 @@ Gitlab/NamespacedClass: ...@@ -1829,6 +1827,7 @@ Gitlab/NamespacedClass:
- 'app/policies/group_policy.rb' - 'app/policies/group_policy.rb'
- 'app/policies/identity_provider_policy.rb' - 'app/policies/identity_provider_policy.rb'
- 'app/policies/instance_metadata_policy.rb' - 'app/policies/instance_metadata_policy.rb'
- 'app/policies/integration_policy.rb'
- 'app/policies/issuable_policy.rb' - 'app/policies/issuable_policy.rb'
- 'app/policies/issue_policy.rb' - 'app/policies/issue_policy.rb'
- 'app/policies/merge_request_policy.rb' - 'app/policies/merge_request_policy.rb'
...@@ -1849,7 +1848,6 @@ Gitlab/NamespacedClass: ...@@ -1849,7 +1848,6 @@ Gitlab/NamespacedClass:
- 'app/policies/release_policy.rb' - 'app/policies/release_policy.rb'
- 'app/policies/repository_policy.rb' - 'app/policies/repository_policy.rb'
- 'app/policies/resource_label_event_policy.rb' - 'app/policies/resource_label_event_policy.rb'
- 'app/policies/service_policy.rb'
- 'app/policies/suggestion_policy.rb' - 'app/policies/suggestion_policy.rb'
- 'app/policies/timebox_policy.rb' - 'app/policies/timebox_policy.rb'
- 'app/policies/timelog_policy.rb' - 'app/policies/timelog_policy.rb'
......
...@@ -49,7 +49,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -49,7 +49,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
def integrations def integrations
return not_found unless instance_level_integrations? return not_found unless instance_level_integrations?
@integrations = Service.find_or_initialize_all_non_project_specific(Service.for_instance).sort_by(&:title) @integrations = Integration.find_or_initialize_all_non_project_specific(Integration.for_instance).sort_by(&:title)
end end
def update def update
......
...@@ -11,7 +11,7 @@ class Admin::IntegrationsController < Admin::ApplicationController ...@@ -11,7 +11,7 @@ class Admin::IntegrationsController < Admin::ApplicationController
private private
def find_or_initialize_non_project_specific_integration(name) def find_or_initialize_non_project_specific_integration(name)
Service.find_or_initialize_non_project_specific_integration(name, instance: true) Integration.find_or_initialize_non_project_specific_integration(name, instance: true)
end end
def scoped_edit_integration_path(integration) def scoped_edit_integration_path(integration)
......
...@@ -9,12 +9,12 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -9,12 +9,12 @@ class Admin::ServicesController < Admin::ApplicationController
feature_category :integrations feature_category :integrations
def index def index
@activated_services = Service.for_template.active.sort_by(&:title) @activated_services = Integration.for_template.active.sort_by(&:title)
@existing_instance_types = Service.for_instance.pluck(:type) # rubocop: disable CodeReuse/ActiveRecord @existing_instance_types = Integration.for_instance.pluck(:type) # rubocop: disable CodeReuse/ActiveRecord
end end
def edit def edit
if integration.nil? || Service.instance_exists_for?(integration.type) if integration.nil? || Integration.instance_exists_for?(integration.type)
redirect_to admin_application_settings_services_path, redirect_to admin_application_settings_services_path,
alert: "Service is unknown or it doesn't exist" alert: "Service is unknown or it doesn't exist"
end end
...@@ -35,7 +35,7 @@ class Admin::ServicesController < Admin::ApplicationController ...@@ -35,7 +35,7 @@ class Admin::ServicesController < Admin::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def integration def integration
@integration ||= Service.find_by(id: params[:id], template: true) @integration ||= Integration.find_by(id: params[:id], template: true)
@service ||= @integration # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/329759 @service ||= @integration # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/329759
end end
alias_method :service, :integration alias_method :service, :integration
......
...@@ -12,11 +12,11 @@ module Groups ...@@ -12,11 +12,11 @@ module Groups
layout 'group_settings' layout 'group_settings'
def index def index
@integrations = Service.find_or_initialize_all_non_project_specific(Service.for_group(group)).sort_by(&:title) @integrations = Integration.find_or_initialize_all_non_project_specific(Integration.for_group(group)).sort_by(&:title)
end end
def edit def edit
@default_integration = Service.default_integration(integration.type, group) @default_integration = Integration.default_integration(integration.type, group)
super super
end end
...@@ -24,7 +24,7 @@ module Groups ...@@ -24,7 +24,7 @@ module Groups
private private
def find_or_initialize_non_project_specific_integration(name) def find_or_initialize_non_project_specific_integration(name)
Service.find_or_initialize_non_project_specific_integration(name, group_id: group.id) Integration.find_or_initialize_non_project_specific_integration(name, group_id: group.id)
end end
def scoped_edit_integration_path(integration) def scoped_edit_integration_path(integration)
......
...@@ -22,7 +22,7 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -22,7 +22,7 @@ class Projects::ServicesController < Projects::ApplicationController
feature_category :integrations feature_category :integrations
def edit def edit
@default_integration = Service.default_integration(service.type, project) @default_integration = Integration.default_integration(service.type, project)
end end
def update def update
......
...@@ -21,7 +21,7 @@ module Resolvers ...@@ -21,7 +21,7 @@ module Resolvers
alias_method :project, :object alias_method :project, :object
def resolve(active: nil, type: nil) def resolve(active: nil, type: nil)
servs = project.services servs = project.integrations
servs = servs.by_active_flag(active) unless active.nil? servs = servs.by_active_flag(active) unless active.nil?
servs = servs.by_type(type) unless type.blank? servs = servs.by_type(type) unless type.blank?
servs servs
......
...@@ -5,7 +5,7 @@ module Types ...@@ -5,7 +5,7 @@ module Types
class ServiceTypeEnum < BaseEnum class ServiceTypeEnum < BaseEnum
graphql_name 'ServiceType' graphql_name 'ServiceType'
::Service.available_services_types(include_dev: false).each do |service_type| ::Integration.available_services_types(include_dev: false).each do |service_type|
value service_type.underscore.upcase, value: service_type, description: "#{service_type} type" value service_type.underscore.upcase, value: service_type, description: "#{service_type} type"
end end
end end
......
...@@ -44,7 +44,7 @@ module UserCalloutsHelper ...@@ -44,7 +44,7 @@ module UserCalloutsHelper
def show_service_templates_deprecated_callout? def show_service_templates_deprecated_callout?
!Gitlab.com? && !Gitlab.com? &&
current_user&.admin? && current_user&.admin? &&
Service.for_template.active.exists? && Integration.for_template.active.exists? &&
!user_dismissed?(SERVICE_TEMPLATES_DEPRECATED_CALLOUT) !user_dismissed?(SERVICE_TEMPLATES_DEPRECATED_CALLOUT)
end end
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
class ChatName < ApplicationRecord class ChatName < ApplicationRecord
LAST_USED_AT_INTERVAL = 1.hour LAST_USED_AT_INTERVAL = 1.hour
belongs_to :service belongs_to :integration, foreign_key: :service_id
belongs_to :user belongs_to :user
validates :user, presence: true validates :user, presence: true
validates :service, presence: true validates :integration, presence: true
validates :team_id, presence: true validates :team_id, presence: true
validates :chat_id, presence: true validates :chat_id, presence: true
......
# frozen_string_literal: true # frozen_string_literal: true
module Integration module HasIntegrations
extend ActiveSupport::Concern extend ActiveSupport::Concern
class_methods do class_methods do
def with_custom_integration_for(integration, page = nil, per = nil) def with_custom_integration_for(integration, page = nil, per = nil)
custom_integration_project_ids = Service custom_integration_project_ids = Integration
.select(:project_id) .select(:project_id)
.where(type: integration.type) .where(type: integration.type)
.where(inherit_from_id: nil) .where(inherit_from_id: nil)
...@@ -17,13 +17,13 @@ module Integration ...@@ -17,13 +17,13 @@ module Integration
end end
def without_integration(integration) def without_integration(integration)
services = Service integrations = Integration
.select('1') .select('1')
.where('services.project_id = projects.id') .where('services.project_id = projects.id')
.where(type: integration.type) .where(type: integration.type)
Project Project
.where('NOT EXISTS (?)', services) .where('NOT EXISTS (?)', integrations)
.where(pending_delete: false) .where(pending_delete: false)
.where(archived: false) .where(archived: false)
end end
......
...@@ -5,11 +5,11 @@ module Services ...@@ -5,11 +5,11 @@ module Services
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
belongs_to :service belongs_to :integration, inverse_of: self.name.underscore.to_sym, foreign_key: :service_id
delegate :activated?, to: :service, allow_nil: true delegate :activated?, to: :integration, allow_nil: true
validates :service, presence: true validates :integration, presence: true
end end
class_methods do class_methods do
......
...@@ -34,7 +34,7 @@ class Group < Namespace ...@@ -34,7 +34,7 @@ class Group < Namespace
has_many :members_and_requesters, as: :source, class_name: 'GroupMember' has_many :members_and_requesters, as: :source, class_name: 'GroupMember'
has_many :milestones has_many :milestones
has_many :services has_many :integrations
has_many :shared_group_links, foreign_key: :shared_with_group_id, class_name: 'GroupGroupLink' has_many :shared_group_links, foreign_key: :shared_with_group_id, class_name: 'GroupGroupLink'
has_many :shared_with_group_links, foreign_key: :shared_group_id, class_name: 'GroupGroupLink' has_many :shared_with_group_links, foreign_key: :shared_group_id, class_name: 'GroupGroupLink'
has_many :shared_groups, through: :shared_group_links, source: :shared_group has_many :shared_groups, through: :shared_group_links, source: :shared_group
...@@ -165,12 +165,12 @@ class Group < Namespace ...@@ -165,12 +165,12 @@ class Group < Namespace
end end
def without_integration(integration) def without_integration(integration)
services = Service integrations = Integration
.select('1') .select('1')
.where('services.group_id = namespaces.id') .where('services.group_id = namespaces.id')
.where(type: integration.type) .where(type: integration.type)
where('NOT EXISTS (?)', services) where('NOT EXISTS (?)', integrations)
end end
# This method can be used only if all groups have the same top-level # This method can be used only if all groups have the same top-level
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
class ServiceHook < WebHook class ServiceHook < WebHook
include Presentable include Presentable
belongs_to :service belongs_to :integration, foreign_key: :service_id
validates :service, presence: true validates :integration, presence: true
def execute(data, hook_name = 'service_hook') def execute(data, hook_name = 'service_hook')
super(data, hook_name) super(data, hook_name)
......
# frozen_string_literal: true # frozen_string_literal: true
# To add new service you should build a class inherited from Service # To add new integration you should build a class inherited from Integration
# and implement a set of methods # and implement a set of methods
class Service < ApplicationRecord class Integration < ApplicationRecord
include Sortable include Sortable
include Importable include Importable
include ProjectServicesLoggable include ProjectServicesLoggable
...@@ -10,19 +10,22 @@ class Service < ApplicationRecord ...@@ -10,19 +10,22 @@ class Service < ApplicationRecord
include FromUnion include FromUnion
include EachBatch include EachBatch
SERVICE_NAMES = %w[ # TODO Rename the table: https://gitlab.com/gitlab-org/gitlab/-/issues/201856
self.table_name = 'services'
INTEGRATION_NAMES = %w[
asana assembla bamboo bugzilla buildkite campfire confluence custom_issue_tracker discord asana assembla bamboo bugzilla buildkite campfire confluence custom_issue_tracker discord
drone_ci emails_on_push ewm external_wiki flowdock hangouts_chat irker jira drone_ci emails_on_push ewm external_wiki flowdock hangouts_chat irker jira
mattermost mattermost_slash_commands microsoft_teams packagist pipelines_email mattermost mattermost_slash_commands microsoft_teams packagist pipelines_email
pivotaltracker prometheus pushover redmine slack slack_slash_commands teamcity unify_circuit webex_teams youtrack pivotaltracker prometheus pushover redmine slack slack_slash_commands teamcity unify_circuit webex_teams youtrack
].freeze ].freeze
PROJECT_SPECIFIC_SERVICE_NAMES = %w[ PROJECT_SPECIFIC_INTEGRATION_NAMES = %w[
datadog jenkins datadog jenkins
].freeze ].freeze
# Fake services to help with local development. # Fake integrations to help with local development.
DEV_SERVICE_NAMES = %w[ DEV_INTEGRATION_NAMES = %w[
mock_ci mock_monitoring mock_ci mock_monitoring
].freeze ].freeze
...@@ -49,9 +52,9 @@ class Service < ApplicationRecord ...@@ -49,9 +52,9 @@ class Service < ApplicationRecord
after_commit :reset_updated_properties after_commit :reset_updated_properties
belongs_to :project, inverse_of: :services belongs_to :project, inverse_of: :integrations
belongs_to :group, inverse_of: :services belongs_to :group, inverse_of: :integrations
has_one :service_hook has_one :service_hook, inverse_of: :integration, foreign_key: :service_id
validates :project_id, presence: true, unless: -> { template? || instance_level? || group_level? } validates :project_id, presence: true, unless: -> { template? || instance_level? || group_level? }
validates :group_id, presence: true, unless: -> { template? || instance_level? || project_level? } validates :group_id, presence: true, unless: -> { template? || instance_level? || project_level? }
...@@ -216,17 +219,17 @@ class Service < ApplicationRecord ...@@ -216,17 +219,17 @@ class Service < ApplicationRecord
end end
def self.services_names def self.services_names
SERVICE_NAMES INTEGRATION_NAMES
end end
def self.dev_services_names def self.dev_services_names
return [] unless Rails.env.development? return [] unless Rails.env.development?
DEV_SERVICE_NAMES DEV_INTEGRATION_NAMES
end end
def self.project_specific_services_names def self.project_specific_services_names
PROJECT_SPECIFIC_SERVICE_NAMES PROJECT_SPECIFIC_INTEGRATION_NAMES
end end
# Returns a list of available service types. # Returns a list of available service types.
...@@ -258,19 +261,19 @@ class Service < ApplicationRecord ...@@ -258,19 +261,19 @@ class Service < ApplicationRecord
private_class_method :service_type_to_model private_class_method :service_type_to_model
def self.build_from_integration(integration, project_id: nil, group_id: nil) def self.build_from_integration(integration, project_id: nil, group_id: nil)
service = integration.dup new_integration = integration.dup
if integration.supports_data_fields? if integration.supports_data_fields?
data_fields = integration.data_fields.dup data_fields = integration.data_fields.dup
data_fields.service = service data_fields.integration = new_integration
end end
service.template = false new_integration.template = false
service.instance = false new_integration.instance = false
service.project_id = project_id new_integration.project_id = project_id
service.group_id = group_id new_integration.group_id = group_id
service.inherit_from_id = integration.id if integration.instance_level? || integration.group_level? new_integration.inherit_from_id = integration.id if integration.instance_level? || integration.group_level?
service new_integration
end end
def self.instance_exists_for?(type) def self.instance_exists_for?(type)
...@@ -368,7 +371,7 @@ class Service < ApplicationRecord ...@@ -368,7 +371,7 @@ class Service < ApplicationRecord
# Expose a list of fields in the JSON endpoint. # Expose a list of fields in the JSON endpoint.
# #
# This list is used in `Service#as_json(only: json_fields)`. # This list is used in `Integration#as_json(only: json_fields)`.
def json_fields def json_fields
%w[active] %w[active]
end end
...@@ -435,7 +438,7 @@ class Service < ApplicationRecord ...@@ -435,7 +438,7 @@ class Service < ApplicationRecord
{ success: result.present?, result: result } { success: result.present?, result: result }
end end
# Disable test for instance-level and group-level services. # Disable test for instance-level and group-level integrations.
# https://gitlab.com/gitlab-org/gitlab/-/issues/213138 # https://gitlab.com/gitlab-org/gitlab/-/issues/213138
def can_test? def can_test?
!(instance_level? || group_level?) !(instance_level? || group_level?)
...@@ -460,7 +463,7 @@ class Service < ApplicationRecord ...@@ -460,7 +463,7 @@ class Service < ApplicationRecord
# Returns a hash of the properties that have been assigned a new value since last save, # Returns a hash of the properties that have been assigned a new value since last save,
# indicating their original values (attr => original value). # indicating their original values (attr => original value).
# ActiveRecord does not provide a mechanism to track changes in serialized keys, # ActiveRecord does not provide a mechanism to track changes in serialized keys,
# so we need a specific implementation for service properties. # so we need a specific implementation for integration properties.
# This allows to track changes to properties set with the accessor methods, # This allows to track changes to properties set with the accessor methods,
# but not direct manipulation of properties hash. # but not direct manipulation of properties hash.
def updated_properties def updated_properties
...@@ -510,4 +513,4 @@ class Service < ApplicationRecord ...@@ -510,4 +513,4 @@ class Service < ApplicationRecord
end end
end end
Service.prepend_mod_with('Service') Integration.prepend_mod_with('Integration')
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'asana' require 'asana'
module Integrations module Integrations
class Asana < Service class Asana < Integration
include ActionView::Helpers::UrlHelper include ActionView::Helpers::UrlHelper
prop_accessor :api_key, :restrict_to_branch prop_accessor :api_key, :restrict_to_branch
......
# frozen_string_literal: true # frozen_string_literal: true
module Integrations module Integrations
class Assembla < Service class Assembla < Integration
prop_accessor :token, :subdomain prop_accessor :token, :subdomain
validates :token, presence: true, if: :activated? validates :token, presence: true, if: :activated?
......
...@@ -19,6 +19,7 @@ class Project < ApplicationRecord ...@@ -19,6 +19,7 @@ class Project < ApplicationRecord
include Presentable include Presentable
include HasRepository include HasRepository
include HasWiki include HasWiki
include HasIntegrations
include CanMoveRepositoryStorage include CanMoveRepositoryStorage
include Routable include Routable
include GroupDescendant include GroupDescendant
...@@ -33,7 +34,6 @@ class Project < ApplicationRecord ...@@ -33,7 +34,6 @@ class Project < ApplicationRecord
include OptionallySearch include OptionallySearch
include FromUnion include FromUnion
include IgnorableColumns include IgnorableColumns
include Integration
include Repositories::CanHousekeepRepository include Repositories::CanHousekeepRepository
include EachBatch include EachBatch
include GitlabRoutingHelper include GitlabRoutingHelper
...@@ -224,7 +224,7 @@ class Project < ApplicationRecord ...@@ -224,7 +224,7 @@ class Project < ApplicationRecord
has_many :source_of_merge_requests, foreign_key: 'source_project_id', class_name: 'MergeRequest' has_many :source_of_merge_requests, foreign_key: 'source_project_id', class_name: 'MergeRequest'
has_many :issues has_many :issues
has_many :labels, class_name: 'ProjectLabel' has_many :labels, class_name: 'ProjectLabel'
has_many :services has_many :integrations
has_many :events has_many :events
has_many :milestones has_many :milestones
has_many :iterations has_many :iterations
...@@ -527,7 +527,7 @@ class Project < ApplicationRecord ...@@ -527,7 +527,7 @@ class Project < ApplicationRecord
scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct } scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct }
scope :with_push, -> { joins(:events).merge(Event.pushed_action) } scope :with_push, -> { joins(:events).merge(Event.pushed_action) }
scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') } scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') }
scope :with_active_jira_services, -> { joins(:services).merge(::JiraService.active) } # rubocop:disable CodeReuse/ServiceClass scope :with_active_jira_services, -> { joins(:integrations).merge(::JiraService.active) } # rubocop:disable CodeReuse/ServiceClass
scope :with_jira_dvcs_cloud, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: true)) } scope :with_jira_dvcs_cloud, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: true)) }
scope :with_jira_dvcs_server, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: false)) } scope :with_jira_dvcs_server, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: false)) }
scope :inc_routes, -> { includes(:route, namespace: :route) } scope :inc_routes, -> { includes(:route, namespace: :route) }
...@@ -1341,7 +1341,7 @@ class Project < ApplicationRecord ...@@ -1341,7 +1341,7 @@ class Project < ApplicationRecord
return unless has_external_issue_tracker? return unless has_external_issue_tracker?
@external_issue_tracker ||= services.external_issue_trackers.first @external_issue_tracker ||= integrations.external_issue_trackers.first
end end
def external_references_supported? def external_references_supported?
...@@ -1357,11 +1357,11 @@ class Project < ApplicationRecord ...@@ -1357,11 +1357,11 @@ class Project < ApplicationRecord
return unless has_external_wiki? return unless has_external_wiki?
@external_wiki ||= services.external_wikis.first @external_wiki ||= integrations.external_wikis.first
end end
def find_or_initialize_services def find_or_initialize_services
available_services_names = Service.available_services_names - disabled_services available_services_names = Integration.available_services_names - disabled_services
available_services_names.map do |service_name| available_services_names.map do |service_name|
find_or_initialize_service(service_name) find_or_initialize_service(service_name)
...@@ -1377,7 +1377,7 @@ class Project < ApplicationRecord ...@@ -1377,7 +1377,7 @@ class Project < ApplicationRecord
def find_or_initialize_service(name) def find_or_initialize_service(name)
return if disabled_services.include?(name) return if disabled_services.include?(name)
find_service(services, name) || build_from_instance_or_template(name) || build_service(name) find_service(integrations, name) || build_from_instance_or_template(name) || build_service(name)
end end
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
...@@ -1390,7 +1390,7 @@ class Project < ApplicationRecord ...@@ -1390,7 +1390,7 @@ class Project < ApplicationRecord
# rubocop: enable CodeReuse/ServiceClass # rubocop: enable CodeReuse/ServiceClass
def ci_services def ci_services
services.where(category: :ci) integrations.where(category: :ci)
end end
def ci_service def ci_service
...@@ -1398,7 +1398,7 @@ class Project < ApplicationRecord ...@@ -1398,7 +1398,7 @@ class Project < ApplicationRecord
end end
def monitoring_services def monitoring_services
services.where(category: :monitoring) integrations.where(category: :monitoring)
end end
def monitoring_service def monitoring_service
...@@ -1476,8 +1476,8 @@ class Project < ApplicationRecord ...@@ -1476,8 +1476,8 @@ class Project < ApplicationRecord
def execute_services(data, hooks_scope = :push_hooks) def execute_services(data, hooks_scope = :push_hooks)
# Call only service hooks that are active for this scope # Call only service hooks that are active for this scope
run_after_commit_or_now do run_after_commit_or_now do
services.public_send(hooks_scope).each do |service| # rubocop:disable GitlabSecurity/PublicSend integrations.public_send(hooks_scope).each do |integration| # rubocop:disable GitlabSecurity/PublicSend
service.async_execute(data) integration.async_execute(data)
end end
end end
end end
...@@ -1487,7 +1487,7 @@ class Project < ApplicationRecord ...@@ -1487,7 +1487,7 @@ class Project < ApplicationRecord
end end
def has_active_services?(hooks_scope = :push_hooks) def has_active_services?(hooks_scope = :push_hooks)
services.public_send(hooks_scope).any? # rubocop:disable GitlabSecurity/PublicSend integrations.public_send(hooks_scope).any? # rubocop:disable GitlabSecurity/PublicSend
end end
def feature_usage def feature_usage
...@@ -2596,22 +2596,22 @@ class Project < ApplicationRecord ...@@ -2596,22 +2596,22 @@ class Project < ApplicationRecord
def build_from_instance_or_template(name) def build_from_instance_or_template(name)
instance = find_service(services_instances, name) instance = find_service(services_instances, name)
return Service.build_from_integration(instance, project_id: id) if instance return Integration.build_from_integration(instance, project_id: id) if instance
template = find_service(services_templates, name) template = find_service(services_templates, name)
return Service.build_from_integration(template, project_id: id) if template return Integration.build_from_integration(template, project_id: id) if template
end end
def build_service(name) def build_service(name)
Service.service_name_to_model(name).new(project_id: id) Integration.service_name_to_model(name).new(project_id: id)
end end
def services_templates def services_templates
@services_templates ||= Service.for_template @services_templates ||= Integration.for_template
end end
def services_instances def services_instances
@services_instances ||= Service.for_instance @services_instances ||= Integration.for_instance
end end
def closest_namespace_setting(name) def closest_namespace_setting(name)
...@@ -2748,11 +2748,11 @@ class Project < ApplicationRecord ...@@ -2748,11 +2748,11 @@ class Project < ApplicationRecord
end end
def cache_has_external_wiki def cache_has_external_wiki
update_column(:has_external_wiki, services.external_wikis.any?) if Gitlab::Database.read_write? update_column(:has_external_wiki, integrations.external_wikis.any?) if Gitlab::Database.read_write?
end end
def cache_has_external_issue_tracker def cache_has_external_issue_tracker
update_column(:has_external_issue_tracker, services.external_issue_trackers.any?) if Gitlab::Database.read_write? update_column(:has_external_issue_tracker, integrations.external_issue_trackers.any?) if Gitlab::Database.read_write?
end end
def active_runners_with_tags def active_runners_with_tags
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# This class is to be removed with 9.1 # This class is to be removed with 9.1
# We should also by then remove BuildsEmailService from database # We should also by then remove BuildsEmailService from database
class BuildsEmailService < Service class BuildsEmailService < Integration
def self.to_param def self.to_param
'builds_email' 'builds_email'
end end
......
# frozen_string_literal: true # frozen_string_literal: true
class CampfireService < Service class CampfireService < Integration
prop_accessor :token, :subdomain, :room prop_accessor :token, :subdomain, :room
validates :token, presence: true, if: :activated? validates :token, presence: true, if: :activated?
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Base class for Chat notifications services # Base class for Chat notifications services
# This class is not meant to be used directly, but only to inherit from. # This class is not meant to be used directly, but only to inherit from.
class ChatNotificationService < Service class ChatNotificationService < Integration
include ChatMessage include ChatMessage
include NotificationBranchSelection include NotificationBranchSelection
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# Base class for CI services # Base class for CI services
# List methods you need to implement to get your CI service # List methods you need to implement to get your CI service
# working with GitLab merge requests # working with GitLab merge requests
class CiService < Service class CiService < Integration
default_value_for :category, 'ci' default_value_for :category, 'ci'
def valid_token?(token) def valid_token?(token)
......
# frozen_string_literal: true # frozen_string_literal: true
class ConfluenceService < Service class ConfluenceService < Integration
include ActionView::Helpers::UrlHelper include ActionView::Helpers::UrlHelper
VALID_SCHEME_MATCH = %r{\Ahttps?\Z}.freeze VALID_SCHEME_MATCH = %r{\Ahttps?\Z}.freeze
......
...@@ -42,9 +42,9 @@ module DataFields ...@@ -42,9 +42,9 @@ module DataFields
end end
included do included do
has_one :issue_tracker_data, autosave: true has_one :issue_tracker_data, autosave: true, inverse_of: :integration, foreign_key: :service_id
has_one :jira_tracker_data, autosave: true has_one :jira_tracker_data, autosave: true, inverse_of: :integration, foreign_key: :service_id
has_one :open_project_tracker_data, autosave: true has_one :open_project_tracker_data, autosave: true, inverse_of: :integration, foreign_key: :service_id
def data_fields def data_fields
raise NotImplementedError raise NotImplementedError
......
# frozen_string_literal: true # frozen_string_literal: true
class DatadogService < Service class DatadogService < Integration
DEFAULT_SITE = 'datadoghq.com' DEFAULT_SITE = 'datadoghq.com'
URL_TEMPLATE = 'https://webhooks-http-intake.logs.%{datadog_site}/v1/input/' URL_TEMPLATE = 'https://webhooks-http-intake.logs.%{datadog_site}/v1/input/'
URL_TEMPLATE_API_KEYS = 'https://app.%{datadog_site}/account/settings#api' URL_TEMPLATE_API_KEYS = 'https://app.%{datadog_site}/account/settings#api'
......
# frozen_string_literal: true # frozen_string_literal: true
class EmailsOnPushService < Service class EmailsOnPushService < Integration
include NotificationBranchSelection include NotificationBranchSelection
RECIPIENTS_LIMIT = 750 RECIPIENTS_LIMIT = 750
......
# frozen_string_literal: true # frozen_string_literal: true
class ExternalWikiService < Service class ExternalWikiService < Integration
include ActionView::Helpers::UrlHelper include ActionView::Helpers::UrlHelper
prop_accessor :external_wiki_url prop_accessor :external_wiki_url
validates :external_wiki_url, presence: true, public_url: true, if: :activated? validates :external_wiki_url, presence: true, public_url: true, if: :activated?
......
# frozen_string_literal: true # frozen_string_literal: true
class FlowdockService < Service class FlowdockService < Integration
include ActionView::Helpers::UrlHelper include ActionView::Helpers::UrlHelper
prop_accessor :token prop_accessor :token
validates :token, presence: true, if: :activated? validates :token, presence: true, if: :activated?
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# This service is scheduled for removal. All records must # This service is scheduled for removal. All records must
# be deleted before the class can be removed. # be deleted before the class can be removed.
# https://gitlab.com/gitlab-org/gitlab/-/issues/27954 # https://gitlab.com/gitlab-org/gitlab/-/issues/27954
class HipchatService < Service class HipchatService < Integration
before_save :prevent_save before_save :prevent_save
def self.to_param def self.to_param
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'uri' require 'uri'
class IrkerService < Service class IrkerService < Integration
prop_accessor :server_host, :server_port, :default_irc_uri prop_accessor :server_host, :server_port, :default_irc_uri
prop_accessor :recipients, :channels prop_accessor :recipients, :channels
boolean_accessor :colorize_messages boolean_accessor :colorize_messages
......
# frozen_string_literal: true # frozen_string_literal: true
class IssueTrackerService < Service class IssueTrackerService < Integration
validate :one_issue_tracker, if: :activated?, on: :manual_change validate :one_issue_tracker, if: :activated?, on: :manual_change
# TODO: we can probably just delegate as part of # TODO: we can probably just delegate as part of
...@@ -143,7 +143,7 @@ class IssueTrackerService < Service ...@@ -143,7 +143,7 @@ class IssueTrackerService < Service
return if template? || instance? return if template? || instance?
return if project.blank? return if project.blank?
if project.services.external_issue_trackers.where.not(id: id).any? if project.integrations.external_issue_trackers.where.not(id: id).any?
errors.add(:base, _('Another issue tracker is already in use. Only one issue tracker service can be active at a time')) errors.add(:base, _('Another issue tracker is already in use. Only one issue tracker service can be active at a time'))
end end
end end
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
# These services integrate with a deployment solution like Prometheus # These services integrate with a deployment solution like Prometheus
# to provide additional features for environments. # to provide additional features for environments.
class MonitoringService < Service class MonitoringService < Integration
default_value_for :category, 'monitoring' default_value_for :category, 'monitoring'
def self.supported_events def self.supported_events
......
# frozen_string_literal: true # frozen_string_literal: true
class PackagistService < Service class PackagistService < Integration
prop_accessor :username, :token, :server prop_accessor :username, :token, :server
validates :username, presence: true, if: :activated? validates :username, presence: true, if: :activated?
......
# frozen_string_literal: true # frozen_string_literal: true
class PipelinesEmailService < Service class PipelinesEmailService < Integration
include NotificationBranchSelection include NotificationBranchSelection
prop_accessor :recipients, :branches_to_be_notified prop_accessor :recipients, :branches_to_be_notified
......
# frozen_string_literal: true # frozen_string_literal: true
class PivotaltrackerService < Service class PivotaltrackerService < Integration
API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits' API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits'
prop_accessor :token, :restrict_to_branch prop_accessor :token, :restrict_to_branch
......
# frozen_string_literal: true # frozen_string_literal: true
class PushoverService < Service class PushoverService < Integration
BASE_URI = 'https://api.pushover.net/1' BASE_URI = 'https://api.pushover.net/1'
prop_accessor :api_key, :user_key, :device, :priority, :sound prop_accessor :api_key, :user_key, :device, :priority, :sound
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Base class for Chat services # Base class for Chat services
# This class is not meant to be used directly, but only to inherrit from. # This class is not meant to be used directly, but only to inherrit from.
class SlashCommandsService < Service class SlashCommandsService < Integration
default_value_for :category, 'chat' default_value_for :category, 'chat'
prop_accessor :token prop_accessor :token
......
...@@ -8,7 +8,7 @@ class ServiceList ...@@ -8,7 +8,7 @@ class ServiceList
end end
def to_array def to_array
[Service, columns, values] [Integration, columns, values]
end end
private private
......
# frozen_string_literal: true # frozen_string_literal: true
class ServicePolicy < BasePolicy class IntegrationPolicy < BasePolicy
delegate(:project) delegate(:project)
end end
...@@ -4,10 +4,10 @@ class ServiceHookPresenter < Gitlab::View::Presenter::Delegated ...@@ -4,10 +4,10 @@ class ServiceHookPresenter < Gitlab::View::Presenter::Delegated
presents :service_hook presents :service_hook
def logs_details_path(log) def logs_details_path(log)
project_service_hook_log_path(service.project, service, log) project_service_hook_log_path(integration.project, integration, log)
end end
def logs_retry_path(log) def logs_retry_path(log)
retry_project_service_hook_log_path(service.project, service, log) retry_project_service_hook_log_path(integration.project, integration, log)
end end
end end
...@@ -20,14 +20,14 @@ module Admin ...@@ -20,14 +20,14 @@ module Admin
def update_inherited_integrations def update_inherited_integrations
propagate_integrations( propagate_integrations(
Service.by_type(integration.type).inherit_from_id(integration.id), Integration.by_type(integration.type).inherit_from_id(integration.id),
PropagateIntegrationInheritWorker PropagateIntegrationInheritWorker
) )
end end
def update_inherited_descendant_integrations def update_inherited_descendant_integrations
propagate_integrations( propagate_integrations(
Service.inherited_descendants_from_self_or_ancestors_from(integration), Integration.inherited_descendants_from_self_or_ancestors_from(integration),
PropagateIntegrationInheritDescendantWorker PropagateIntegrationInheritDescendantWorker
) )
end end
......
...@@ -10,7 +10,7 @@ class BulkCreateIntegrationService ...@@ -10,7 +10,7 @@ class BulkCreateIntegrationService
def execute def execute
service_list = ServiceList.new(batch, service_hash, association).to_array service_list = ServiceList.new(batch, service_hash, association).to_array
Service.transaction do Integration.transaction do
results = bulk_insert(*service_list) results = bulk_insert(*service_list)
if integration.data_fields_present? if integration.data_fields_present?
......
...@@ -8,8 +8,8 @@ class BulkUpdateIntegrationService ...@@ -8,8 +8,8 @@ class BulkUpdateIntegrationService
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def execute def execute
Service.transaction do Integration.transaction do
Service.where(id: batch.select(:id)).update_all(service_hash) Integration.where(id: batch.select(:id)).update_all(service_hash)
if integration.data_fields_present? if integration.data_fields_present?
integration.data_fields.class.where(service_id: batch.select(:id)).update_all(data_fields_hash) integration.data_fields.class.where(service_id: batch.select(:id)).update_all(data_fields_hash)
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
module ChatNames module ChatNames
class FindUserService class FindUserService
def initialize(service, params) def initialize(integration, params)
@service = service @integration = integration
@params = params @params = params
end end
...@@ -20,7 +20,7 @@ module ChatNames ...@@ -20,7 +20,7 @@ module ChatNames
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def find_chat_name def find_chat_name
ChatName.find_by( ChatName.find_by(
service: @service, integration: @integration,
team_id: @params[:team_id], team_id: @params[:team_id],
chat_id: @params[:user_id] chat_id: @params[:user_id]
) )
......
...@@ -37,7 +37,7 @@ module Groups ...@@ -37,7 +37,7 @@ module Groups
Group.transaction do Group.transaction do
if @group.save if @group.save
@group.add_owner(current_user) @group.add_owner(current_user)
Service.create_from_active_default_integrations(@group, :group_id) Integration.create_from_active_default_integrations(@group, :group_id)
OnboardingProgress.onboard(@group) OnboardingProgress.onboard(@group)
end end
end end
......
...@@ -200,12 +200,12 @@ module Groups ...@@ -200,12 +200,12 @@ module Groups
end end
def update_integrations def update_integrations
@group.services.inherit.delete_all @group.integrations.inherit.delete_all
Service.create_from_active_default_integrations(@group, :group_id) Integration.create_from_active_default_integrations(@group, :group_id)
end end
def propagate_integrations def propagate_integrations
@group.services.inherit.each do |integration| @group.integrations.inherit.each do |integration|
PropagateIntegrationWorker.perform_async(integration.id) PropagateIntegrationWorker.perform_async(integration.id)
end end
end end
......
...@@ -167,7 +167,7 @@ module Projects ...@@ -167,7 +167,7 @@ module Projects
@project.create_or_update_import_data(data: @import_data[:data], credentials: @import_data[:credentials]) if @import_data @project.create_or_update_import_data(data: @import_data[:data], credentials: @import_data[:credentials]) if @import_data
if @project.save if @project.save
Service.create_from_active_default_integrations(@project, :project_id, with_templates: true) Integration.create_from_active_default_integrations(@project, :project_id, with_templates: true)
@project.create_labels unless @project.gitlab_project_import? @project.create_labels unless @project.gitlab_project_import?
......
...@@ -223,8 +223,8 @@ module Projects ...@@ -223,8 +223,8 @@ module Projects
end end
def update_integrations def update_integrations
project.services.inherit.delete_all project.integrations.inherit.delete_all
Service.create_from_active_default_integrations(project, :project_id) Integration.create_from_active_default_integrations(project, :project_id)
end end
end end
end end
......
- service = chat_name.service - integration = chat_name.integration
- project = service.project - project = integration.project
%tr %tr
%td %td
%strong %strong
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
%td %td
%strong %strong
- if can?(current_user, :admin_project, project) - if can?(current_user, :admin_project, project)
= link_to service.title, edit_project_service_path(project, service) = link_to integration.title, edit_project_service_path(project, integration)
- else - else
= service.title = integration.title
%td %td
= chat_name.team_domain = chat_name.team_domain
%td %td
......
...@@ -11,10 +11,10 @@ class ProjectServiceWorker # rubocop:disable Scalability/IdempotentWorker ...@@ -11,10 +11,10 @@ class ProjectServiceWorker # rubocop:disable Scalability/IdempotentWorker
def perform(hook_id, data) def perform(hook_id, data)
data = data.with_indifferent_access data = data.with_indifferent_access
service = Service.find(hook_id) integration = Integration.find(hook_id)
service.execute(data) integration.execute(data)
rescue StandardError => error rescue StandardError => error
service_class = service&.class&.name || "Not Found" integration_class = integration&.class&.name || "Not Found"
logger.error class: self.class.name, service_class: service_class, message: error.message logger.error class: self.class.name, service_class: integration_class, message: error.message
end end
end end
...@@ -11,7 +11,7 @@ class PropagateIntegrationGroupWorker ...@@ -11,7 +11,7 @@ class PropagateIntegrationGroupWorker
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def perform(integration_id, min_id, max_id) def perform(integration_id, min_id, max_id)
integration = Service.find_by_id(integration_id) integration = Integration.find_by_id(integration_id)
return unless integration return unless integration
batch = if integration.instance_level? batch = if integration.instance_level?
......
...@@ -11,10 +11,10 @@ class PropagateIntegrationInheritDescendantWorker ...@@ -11,10 +11,10 @@ class PropagateIntegrationInheritDescendantWorker
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def perform(integration_id, min_id, max_id) def perform(integration_id, min_id, max_id)
integration = Service.find_by_id(integration_id) integration = Integration.find_by_id(integration_id)
return unless integration return unless integration
batch = Service.inherited_descendants_from_self_or_ancestors_from(integration).where(id: min_id..max_id) batch = Integration.inherited_descendants_from_self_or_ancestors_from(integration).where(id: min_id..max_id)
BulkUpdateIntegrationService.new(integration, batch).execute BulkUpdateIntegrationService.new(integration, batch).execute
end end
......
...@@ -11,10 +11,10 @@ class PropagateIntegrationInheritWorker ...@@ -11,10 +11,10 @@ class PropagateIntegrationInheritWorker
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def perform(integration_id, min_id, max_id) def perform(integration_id, min_id, max_id)
integration = Service.find_by_id(integration_id) integration = Integration.find_by_id(integration_id)
return unless integration return unless integration
batch = Service.where(id: min_id..max_id).by_type(integration.type).inherit_from_id(integration.id) batch = Integration.where(id: min_id..max_id).by_type(integration.type).inherit_from_id(integration.id)
BulkUpdateIntegrationService.new(integration, batch).execute BulkUpdateIntegrationService.new(integration, batch).execute
end end
......
...@@ -11,7 +11,7 @@ class PropagateIntegrationProjectWorker ...@@ -11,7 +11,7 @@ class PropagateIntegrationProjectWorker
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def perform(integration_id, min_id, max_id) def perform(integration_id, min_id, max_id)
integration = Service.find_by_id(integration_id) integration = Integration.find_by_id(integration_id)
return unless integration return unless integration
batch = Project.where(id: min_id..max_id).without_integration(integration) batch = Project.where(id: min_id..max_id).without_integration(integration)
......
...@@ -12,6 +12,6 @@ class PropagateIntegrationWorker ...@@ -12,6 +12,6 @@ class PropagateIntegrationWorker
# TODO: Keep overwrite parameter for backwards compatibility. Remove after >= 14.0 # TODO: Keep overwrite parameter for backwards compatibility. Remove after >= 14.0
# https://gitlab.com/gitlab-org/gitlab/-/issues/255382 # https://gitlab.com/gitlab-org/gitlab/-/issues/255382
def perform(integration_id, overwrite = nil) def perform(integration_id, overwrite = nil)
Admin::PropagateIntegrationService.propagate(Service.find(integration_id)) Admin::PropagateIntegrationService.propagate(Integration.find(integration_id))
end end
end end
...@@ -14,7 +14,7 @@ class PropagateServiceTemplateWorker # rubocop:disable Scalability/IdempotentWor ...@@ -14,7 +14,7 @@ class PropagateServiceTemplateWorker # rubocop:disable Scalability/IdempotentWor
def perform(template_id) def perform(template_id)
return unless try_obtain_lease_for(template_id) return unless try_obtain_lease_for(template_id)
Admin::PropagateServiceTemplate.propagate(Service.find_by(id: template_id)) Admin::PropagateServiceTemplate.propagate(Integration.find_by(id: template_id))
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
......
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
class DeleteKubernetesServices < ActiveRecord::Migration[5.2] class DeleteKubernetesServices < ActiveRecord::Migration[5.2]
DOWNTIME = false DOWNTIME = false
class Service < ActiveRecord::Base
self.table_name = 'services'
self.inheritance_column = :_type_disabled
end
def up def up
Service.where(type: "KubernetesService").delete_all Service.where(type: "KubernetesService").delete_all
end end
......
...@@ -31,7 +31,7 @@ Completed 500 Internal Server Error in 497ms (ActiveRecord: 32.2ms) ...@@ -31,7 +31,7 @@ Completed 500 Internal Server Error in 497ms (ActiveRecord: 32.2ms)
ActionView::Template::Error (The single-table inheritance mechanism failed to locate the subclass: 'GithubService'. This ActionView::Template::Error (The single-table inheritance mechanism failed to locate the subclass: 'GithubService'. This
error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this
column if you didn't intend it to be used for storing the inheritance class or overwrite Service.inheritance_column to column if you didn't intend it to be used for storing the inheritance class or overwrite Integration.inheritance_column to
use another column for that information.) use another column for that information.)
``` ```
...@@ -42,13 +42,13 @@ to avoid getting this error, you need to remove all instances of the ...@@ -42,13 +42,13 @@ to avoid getting this error, you need to remove all instances of the
**Omnibus Installation** **Omnibus Installation**
```shell ```shell
sudo gitlab-rails runner "Service.where(type: ['GithubService']).delete_all" sudo gitlab-rails runner "Integration.where(type: ['GithubService']).delete_all"
``` ```
**Source Installation** **Source Installation**
```shell ```shell
bundle exec rails runner "Service.where(type: ['GithubService']).delete_all" production bundle exec rails runner "Integration.where(type: ['GithubService']).delete_all" production
``` ```
NOTE: NOTE:
......
# frozen_string_literal: true # frozen_string_literal: true
module EE module EE
module Service module Integration
extend ActiveSupport::Concern extend ActiveSupport::Concern
EE_COM_PROJECT_SPECIFIC_SERVICE_NAMES = %w[ EE_COM_PROJECT_SPECIFIC_INTEGRATION_NAMES = %w[
gitlab_slack_application gitlab_slack_application
].freeze ].freeze
EE_PROJECT_SPECIFIC_SERVICE_NAMES = %w[ EE_PROJECT_SPECIFIC_INTEGRATION_NAMES = %w[
github github
].freeze ].freeze
...@@ -17,13 +17,9 @@ module EE ...@@ -17,13 +17,9 @@ module EE
override :project_specific_services_names override :project_specific_services_names
def project_specific_services_names def project_specific_services_names
services = super + EE_PROJECT_SPECIFIC_SERVICE_NAMES integrations = super + EE_PROJECT_SPECIFIC_INTEGRATION_NAMES
integrations += EE_COM_PROJECT_SPECIFIC_INTEGRATION_NAMES if ::Gitlab.com?
if ::Gitlab.com? integrations
services + EE_COM_PROJECT_SPECIFIC_SERVICE_NAMES
else
services
end
end end
end end
end end
......
...@@ -143,7 +143,7 @@ module EE ...@@ -143,7 +143,7 @@ module EE
scope :for_plan_name, -> (name) { joins(namespace: { gitlab_subscription: :hosted_plan }).where(plans: { name: name }) } scope :for_plan_name, -> (name) { joins(namespace: { gitlab_subscription: :hosted_plan }).where(plans: { name: name }) }
scope :requiring_code_owner_approval, scope :requiring_code_owner_approval,
-> { joins(:protected_branches).where(protected_branches: { code_owner_approval_required: true }) } -> { joins(:protected_branches).where(protected_branches: { code_owner_approval_required: true }) }
scope :with_active_services, -> { joins(:services).merge(::Service.active) } scope :with_active_services, -> { joins(:integrations).merge(::Integration.active) }
scope :github_imported, -> { where(import_type: 'github') } scope :github_imported, -> { where(import_type: 'github') }
scope :with_protected_branches, -> { joins(:protected_branches) } scope :with_protected_branches, -> { joins(:protected_branches) }
scope :with_repositories_enabled, -> { joins(:project_feature).where(project_features: { repository_access_level: ::ProjectFeature::ENABLED }) } scope :with_repositories_enabled, -> { joins(:project_feature).where(project_features: { repository_access_level: ::ProjectFeature::ENABLED }) }
......
# frozen_string_literal: true # frozen_string_literal: true
class GithubService < Service class GithubService < Integration
include Gitlab::Routing include Gitlab::Routing
include ActionView::Helpers::UrlHelper include ActionView::Helpers::UrlHelper
......
# frozen_string_literal: true # frozen_string_literal: true
class GitlabSlackApplicationService < Service class GitlabSlackApplicationService < Integration
default_value_for :category, 'chat' default_value_for :category, 'chat'
has_one :slack_integration, foreign_key: :service_id has_one :slack_integration, foreign_key: :service_id
......
# frozen_string_literal: true # frozen_string_literal: true
class SlackIntegration < ApplicationRecord class SlackIntegration < ApplicationRecord
belongs_to :service belongs_to :integration, foreign_key: :service_id
validates :team_id, presence: true validates :team_id, presence: true
validates :team_name, presence: true validates :team_name, presence: true
...@@ -9,11 +9,11 @@ class SlackIntegration < ApplicationRecord ...@@ -9,11 +9,11 @@ class SlackIntegration < ApplicationRecord
uniqueness: { scope: :team_id, message: 'This alias has already been taken' }, uniqueness: { scope: :team_id, message: 'This alias has already been taken' },
length: 2..80 length: 2..80
validates :user_id, presence: true validates :user_id, presence: true
validates :service, presence: true validates :integration, presence: true
after_commit :update_active_status_of_service, on: [:create, :destroy] after_commit :update_active_status_of_integration, on: [:create, :destroy]
def update_active_status_of_service def update_active_status_of_integration
service.update_active_status integration.update_active_status
end end
end end
...@@ -37,7 +37,7 @@ module Projects ...@@ -37,7 +37,7 @@ module Projects
service = project.gitlab_slack_application_service service = project.gitlab_slack_application_service
chat_name = ChatName.find_by( chat_name = ChatName.find_by(
service: service.id, service_id: service.id,
team_id: slack_data['team_id'], team_id: slack_data['team_id'],
chat_id: slack_data['user_id'] chat_id: slack_data['user_id']
) )
......
...@@ -16,20 +16,20 @@ module SlashCommands ...@@ -16,20 +16,20 @@ module SlashCommands
return Gitlab::SlashCommands::ApplicationHelp.new(nil, params).execute return Gitlab::SlashCommands::ApplicationHelp.new(nil, params).execute
end end
unless integration = find_integration unless slack_integration = find_slack_integration
error_message = 'GitLab error: project or alias not found' error_message = 'GitLab error: project or alias not found'
return Gitlab::SlashCommands::Presenters::Error.new(error_message).message return Gitlab::SlashCommands::Presenters::Error.new(error_message).message
end end
service = integration.service integration = slack_integration.integration
project = service.project project = integration.project
chat_user = ChatNames::FindUserService.new(service, params).execute chat_user = ChatNames::FindUserService.new(integration, params).execute
if chat_user&.user if chat_user&.user
Gitlab::SlashCommands::Command.new(project, chat_user, params).execute Gitlab::SlashCommands::Command.new(project, chat_user, params).execute
else else
url = ChatNames::AuthorizeUserService.new(service, params).execute url = ChatNames::AuthorizeUserService.new(integration, params).execute
Gitlab::SlashCommands::Presenters::Access.new(url).authorize Gitlab::SlashCommands::Presenters::Access.new(url).authorize
end end
end end
...@@ -49,7 +49,7 @@ module SlashCommands ...@@ -49,7 +49,7 @@ module SlashCommands
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def find_integration def find_slack_integration
SlackIntegration.find_by(team_id: params[:team_id], alias: project_alias) SlackIntegration.find_by(team_id: params[:team_id], alias: project_alias)
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
......
...@@ -7,6 +7,6 @@ FactoryBot.define do ...@@ -7,6 +7,6 @@ FactoryBot.define do
sequence(:team_name) { |n| "team#{n}" } sequence(:team_name) { |n| "team#{n}" }
sequence(:alias) { |n| "namespace#{n}/project_name#{n}" } sequence(:alias) { |n| "namespace#{n}/project_name#{n}" }
service factory: :gitlab_slack_application_service integration factory: :gitlab_slack_application_service
end end
end end
...@@ -13,7 +13,7 @@ RSpec.describe 'Slack application' do ...@@ -13,7 +13,7 @@ RSpec.describe 'Slack application' do
gitlab_sign_in(user) gitlab_sign_in(user)
project.add_maintainer(user) project.add_maintainer(user)
create(:slack_integration, service: service) create(:slack_integration, integration: service)
allow(Gitlab).to receive(:com?).and_return(true) allow(Gitlab).to receive(:com?).and_return(true)
allow(Gitlab::CurrentSettings).to receive(:slack_app_enabled).and_return(true) allow(Gitlab::CurrentSettings).to receive(:slack_app_enabled).and_return(true)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Service do RSpec.describe Integration do
describe '.available_services_names' do describe '.available_services_names' do
it { expect(described_class.available_services_names).to include('github') } it { expect(described_class.available_services_names).to include('github') }
end end
...@@ -17,7 +17,7 @@ RSpec.describe Service do ...@@ -17,7 +17,7 @@ RSpec.describe Service do
it do it do
expect(described_class.project_specific_services_names) expect(described_class.project_specific_services_names)
.to include(*described_class::EE_PROJECT_SPECIFIC_SERVICE_NAMES) .to include(*described_class::EE_PROJECT_SPECIFIC_INTEGRATION_NAMES)
end end
end end
...@@ -26,7 +26,7 @@ RSpec.describe Service do ...@@ -26,7 +26,7 @@ RSpec.describe Service do
it do it do
expect(described_class.project_specific_services_names) expect(described_class.project_specific_services_names)
.to include(*described_class::EE_PROJECT_SPECIFIC_SERVICE_NAMES, *Service::EE_COM_PROJECT_SPECIFIC_SERVICE_NAMES) .to include(*described_class::EE_PROJECT_SPECIFIC_INTEGRATION_NAMES, *Integration::EE_COM_PROJECT_SPECIFIC_INTEGRATION_NAMES)
end end
end end
end end
......
...@@ -384,7 +384,7 @@ RSpec.describe JiraService do ...@@ -384,7 +384,7 @@ RSpec.describe JiraService do
allow(jira_service).to receive(:vulnerabilities_issuetype).and_return('10001') allow(jira_service).to receive(:vulnerabilities_issuetype).and_return('10001')
end end
let(:expected_new_issue_url) { '/secure/CreateIssueDetails!init.jspa?pid=11223&issuetype=10001&summary=Special+Summary%21%3F&description=%2AID%2A%3A+2%0A_Issue_%3A+%21' } let(:expected_new_issue_url) { "#{jira_service.url}/secure/CreateIssueDetails!init.jspa?pid=11223&issuetype=10001&summary=Special+Summary%21%3F&description=%2AID%2A%3A+2%0A_Issue_%3A+%21" }
subject(:new_issue_url) { jira_service.new_issue_url_with_predefined_fields("Special Summary!?", "*ID*: 2\n_Issue_: !") } subject(:new_issue_url) { jira_service.new_issue_url_with_predefined_fields("Special Summary!?", "*ID*: 2\n_Issue_: !") }
......
...@@ -4,7 +4,7 @@ require 'spec_helper' ...@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe SlackIntegration do RSpec.describe SlackIntegration do
describe "Associations" do describe "Associations" do
it { is_expected.to belong_to(:service) } it { is_expected.to belong_to(:integration) }
end end
describe 'Validations' do describe 'Validations' do
...@@ -12,6 +12,6 @@ RSpec.describe SlackIntegration do ...@@ -12,6 +12,6 @@ RSpec.describe SlackIntegration do
it { is_expected.to validate_presence_of(:team_name) } it { is_expected.to validate_presence_of(:team_name) }
it { is_expected.to validate_presence_of(:alias) } it { is_expected.to validate_presence_of(:alias) }
it { is_expected.to validate_presence_of(:user_id) } it { is_expected.to validate_presence_of(:user_id) }
it { is_expected.to validate_presence_of(:service) } it { is_expected.to validate_presence_of(:integration) }
end end
end end
...@@ -39,7 +39,7 @@ RSpec.describe SlashCommands::GlobalSlackHandler do ...@@ -39,7 +39,7 @@ RSpec.describe SlashCommands::GlobalSlackHandler do
enable_slack_application(project) enable_slack_application(project)
slack_integration = create(:slack_integration, service: project.gitlab_slack_application_service) slack_integration = create(:slack_integration, integration: project.gitlab_slack_application_service)
slack_integration.update(alias: project.full_path) slack_integration.update(alias: project.full_path)
handler_with_valid_token( handler_with_valid_token(
...@@ -54,7 +54,7 @@ RSpec.describe SlashCommands::GlobalSlackHandler do ...@@ -54,7 +54,7 @@ RSpec.describe SlashCommands::GlobalSlackHandler do
enable_slack_application(project) enable_slack_application(project)
slack_integration = create(:slack_integration, service: project.gitlab_slack_application_service) slack_integration = create(:slack_integration, integration: project.gitlab_slack_application_service)
handler_with_valid_token( handler_with_valid_token(
text: "fake/fake issue new title", text: "fake/fake issue new title",
...@@ -68,7 +68,7 @@ RSpec.describe SlashCommands::GlobalSlackHandler do ...@@ -68,7 +68,7 @@ RSpec.describe SlashCommands::GlobalSlackHandler do
enable_slack_application(project) enable_slack_application(project)
slack_integration = create(:slack_integration, service: project.gitlab_slack_application_service) slack_integration = create(:slack_integration, integration: project.gitlab_slack_application_service)
slack_integration.update(alias: project.full_path) slack_integration.update(alias: project.full_path)
handler_with_valid_token( handler_with_valid_token(
......
...@@ -72,7 +72,7 @@ module API ...@@ -72,7 +72,7 @@ module API
success Entities::ProjectServiceBasic success Entities::ProjectServiceBasic
end end
get ":id/services" do get ":id/services" do
services = user_project.services.active services = user_project.integrations.active
present services, with: Entities::ProjectServiceBasic present services, with: Entities::ProjectServiceBasic
end end
...@@ -133,7 +133,7 @@ module API ...@@ -133,7 +133,7 @@ module API
TRIGGER_SERVICES.each do |service_slug, settings| TRIGGER_SERVICES.each do |service_slug, settings|
helpers do helpers do
def slash_command_service(project, service_slug, params) def slash_command_service(project, service_slug, params)
project.services.active.find do |service| project.integrations.active.find do |service|
service.try(:token) == params[:token] && service.to_param == service_slug.underscore service.try(:token) == params[:token] && service.to_param == service_slug.underscore
end end
end end
......
...@@ -156,9 +156,9 @@ module Gitlab ...@@ -156,9 +156,9 @@ module Gitlab
underscored_service = matched_login['service'].underscore underscored_service = matched_login['service'].underscore
if Service.available_services_names.include?(underscored_service) if Integration.available_services_names.include?(underscored_service)
# We treat underscored_service as a trusted input because it is included # We treat underscored_service as a trusted input because it is included
# in the Service.available_services_names allowlist. # in the Integration.available_services_names allowlist.
service = project.public_send("#{underscored_service}_service") # rubocop:disable GitlabSecurity/PublicSend service = project.public_send("#{underscored_service}_service") # rubocop:disable GitlabSecurity/PublicSend
if service && service.activated? && service.valid_token?(password) if service && service.activated? && service.valid_token?(password)
......
...@@ -11,9 +11,9 @@ module Gitlab ...@@ -11,9 +11,9 @@ module Gitlab
# #
# build - A `Ci::Build` that executed a chat command. # build - A `Ci::Build` that executed a chat command.
def self.responder_for(build) def self.responder_for(build)
service = build.pipeline.chat_data&.chat_name&.service integration = build.pipeline.chat_data&.chat_name&.integration
if (responder = service.try(:chat_responder)) if (responder = integration.try(:chat_responder))
responder.new(build) responder.new(build)
end end
end end
......
...@@ -132,6 +132,7 @@ excluded_attributes: ...@@ -132,6 +132,7 @@ excluded_attributes:
- :avatar - :avatar
- :import_type - :import_type
- :import_source - :import_source
- :integrations
- :mirror - :mirror
- :runners_token - :runners_token
- :runners_token_encrypted - :runners_token_encrypted
......
...@@ -426,15 +426,15 @@ module Gitlab ...@@ -426,15 +426,15 @@ module Gitlab
def services_usage def services_usage
# rubocop: disable UsageData/LargeTable: # rubocop: disable UsageData/LargeTable:
Service.available_services_names.each_with_object({}) do |service_name, response| Integration.available_services_names.each_with_object({}) do |service_name, response|
service_type = Service.service_name_to_type(service_name) service_type = Integration.service_name_to_type(service_name)
response["projects_#{service_name}_active".to_sym] = count(Service.active.where.not(project: nil).where(type: service_type)) response["projects_#{service_name}_active".to_sym] = count(Integration.active.where.not(project: nil).where(type: service_type))
response["groups_#{service_name}_active".to_sym] = count(Service.active.where.not(group: nil).where(type: service_type)) response["groups_#{service_name}_active".to_sym] = count(Integration.active.where.not(group: nil).where(type: service_type))
response["templates_#{service_name}_active".to_sym] = count(Service.active.where(template: true, type: service_type)) response["templates_#{service_name}_active".to_sym] = count(Integration.active.where(template: true, type: service_type))
response["instances_#{service_name}_active".to_sym] = count(Service.active.where(instance: true, type: service_type)) response["instances_#{service_name}_active".to_sym] = count(Integration.active.where(instance: true, type: service_type))
response["projects_inheriting_#{service_name}_active".to_sym] = count(Service.active.where.not(project: nil).where.not(inherit_from_id: nil).where(type: service_type)) response["projects_inheriting_#{service_name}_active".to_sym] = count(Integration.active.where.not(project: nil).where.not(inherit_from_id: nil).where(type: service_type))
response["groups_inheriting_#{service_name}_active".to_sym] = count(Service.active.where.not(group: nil).where.not(inherit_from_id: nil).where(type: service_type)) response["groups_inheriting_#{service_name}_active".to_sym] = count(Integration.active.where.not(group: nil).where.not(inherit_from_id: nil).where(type: service_type))
end.merge(jira_usage, jira_import_usage) end.merge(jira_usage, jira_import_usage)
# rubocop: enable UsageData/LargeTable: # rubocop: enable UsageData/LargeTable:
end end
......
...@@ -10,7 +10,7 @@ RSpec.describe Admin::IntegrationsController do ...@@ -10,7 +10,7 @@ RSpec.describe Admin::IntegrationsController do
end end
describe '#edit' do describe '#edit' do
Service.available_services_names.each do |integration_name| Integration.available_services_names.each do |integration_name|
context "#{integration_name}" do context "#{integration_name}" do
it 'successfully displays the template' do it 'successfully displays the template' do
get :edit, params: { id: integration_name } get :edit, params: { id: integration_name }
...@@ -27,7 +27,7 @@ RSpec.describe Admin::IntegrationsController do ...@@ -27,7 +27,7 @@ RSpec.describe Admin::IntegrationsController do
end end
it 'returns 404' do it 'returns 404' do
get :edit, params: { id: Service.available_services_names.sample } get :edit, params: { id: Integration.available_services_names.sample }
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:not_found)
end end
......
...@@ -36,7 +36,7 @@ RSpec.describe Groups::Settings::IntegrationsController do ...@@ -36,7 +36,7 @@ RSpec.describe Groups::Settings::IntegrationsController do
describe '#edit' do describe '#edit' do
context 'when user is not owner' do context 'when user is not owner' do
it 'renders not_found' do it 'renders not_found' do
get :edit, params: { group_id: group, id: Service.available_services_names(include_project_specific: false).sample } get :edit, params: { group_id: group, id: Integration.available_services_names(include_project_specific: false).sample }
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:not_found)
end end
...@@ -47,7 +47,7 @@ RSpec.describe Groups::Settings::IntegrationsController do ...@@ -47,7 +47,7 @@ RSpec.describe Groups::Settings::IntegrationsController do
group.add_owner(user) group.add_owner(user)
end end
Service.available_services_names(include_project_specific: false).each do |integration_name| Integration.available_services_names(include_project_specific: false).each do |integration_name|
context "#{integration_name}" do context "#{integration_name}" do
it 'successfully displays the template' do it 'successfully displays the template' do
get :edit, params: { group_id: group, id: integration_name } get :edit, params: { group_id: group, id: integration_name }
......
...@@ -60,7 +60,7 @@ RSpec.describe Projects::MattermostsController do ...@@ -60,7 +60,7 @@ RSpec.describe Projects::MattermostsController do
it 'redirects to the new page' do it 'redirects to the new page' do
subject subject
service = project.services.last service = project.integrations.last
expect(subject).to redirect_to(edit_project_service_url(project, service)) expect(subject).to redirect_to(edit_project_service_url(project, service))
end end
......
...@@ -19,7 +19,7 @@ RSpec.describe Projects::ServicesController do ...@@ -19,7 +19,7 @@ RSpec.describe Projects::ServicesController do
describe '#test' do describe '#test' do
context 'when can_test? returns false' do context 'when can_test? returns false' do
it 'renders 404' do it 'renders 404' do
allow_any_instance_of(Service).to receive(:can_test?).and_return(false) allow_any_instance_of(Integration).to receive(:can_test?).and_return(false)
put :test, params: project_params put :test, params: project_params
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
FactoryBot.define do FactoryBot.define do
factory :chat_name, class: 'ChatName' do factory :chat_name, class: 'ChatName' do
user factory: :user user
service factory: :service integration
team_id { 'T0001' } team_id { 'T0001' }
team_domain { 'Awesome Team' } team_domain { 'Awesome Team' }
......
...@@ -4,15 +4,15 @@ ...@@ -4,15 +4,15 @@
# The factories are used when creating integrations. # The factories are used when creating integrations.
FactoryBot.define do FactoryBot.define do
factory :jira_tracker_data do factory :jira_tracker_data do
service integration factory: :jira_service
end end
factory :issue_tracker_data do factory :issue_tracker_data do
service integration
end end
factory :open_project_tracker_data do factory :open_project_tracker_data do
service integration factory: :open_project_service
url { 'http://openproject.example.com'} url { 'http://openproject.example.com'}
token { 'supersecret' } token { 'supersecret' }
project_identifier_code { 'PRJ-1' } project_identifier_code { 'PRJ-1' }
......
# frozen_string_literal: true # frozen_string_literal: true
FactoryBot.define do FactoryBot.define do
factory :service do factory :integration, aliases: [:service] do
project project
type { 'Service' } type { 'Integration' }
end end
factory :custom_issue_tracker_service, class: 'CustomIssueTrackerService' do factory :custom_issue_tracker_service, class: 'CustomIssueTrackerService' do
...@@ -65,10 +65,10 @@ FactoryBot.define do ...@@ -65,10 +65,10 @@ FactoryBot.define do
deployment_type { 'cloud' } deployment_type { 'cloud' }
end end
before(:create) do |service, evaluator| after(:build) do |integration, evaluator|
if evaluator.create_data if evaluator.create_data
create(:jira_tracker_data, service: service, integration.jira_tracker_data = build(:jira_tracker_data,
url: evaluator.url, api_url: evaluator.api_url, integration: integration, url: evaluator.url, api_url: evaluator.api_url,
jira_issue_transition_automatic: evaluator.jira_issue_transition_automatic, jira_issue_transition_automatic: evaluator.jira_issue_transition_automatic,
jira_issue_transition_id: evaluator.jira_issue_transition_id, jira_issue_transition_id: evaluator.jira_issue_transition_id,
username: evaluator.username, password: evaluator.password, issues_enabled: evaluator.issues_enabled, username: evaluator.username, password: evaluator.password, issues_enabled: evaluator.issues_enabled,
...@@ -117,10 +117,11 @@ FactoryBot.define do ...@@ -117,10 +117,11 @@ FactoryBot.define do
new_issue_url { 'http://new-issue.example.com' } new_issue_url { 'http://new-issue.example.com' }
end end
before(:create) do |service, evaluator| after(:build) do |integration, evaluator|
if evaluator.create_data if evaluator.create_data
create(:issue_tracker_data, service: service, integration.issue_tracker_data = build(:issue_tracker_data,
project_url: evaluator.project_url, issues_url: evaluator.issues_url, new_issue_url: evaluator.new_issue_url integration: integration, project_url: evaluator.project_url,
issues_url: evaluator.issues_url, new_issue_url: evaluator.new_issue_url
) )
end end
end end
...@@ -145,9 +146,9 @@ FactoryBot.define do ...@@ -145,9 +146,9 @@ FactoryBot.define do
project_identifier_code { 'PRJ-1' } project_identifier_code { 'PRJ-1' }
end end
before(:create) do |service, evaluator| after(:build) do |integration, evaluator|
create(:open_project_tracker_data, service: service, integration.open_project_tracker_data = build(:open_project_tracker_data,
url: evaluator.url, api_url: evaluator.api_url, token: evaluator.token, integration: integration, url: evaluator.url, api_url: evaluator.api_url, token: evaluator.token,
closed_status_id: evaluator.closed_status_id, project_identifier_code: evaluator.project_identifier_code closed_status_id: evaluator.closed_status_id, project_identifier_code: evaluator.project_identifier_code
) )
end end
...@@ -180,7 +181,7 @@ FactoryBot.define do ...@@ -180,7 +181,7 @@ FactoryBot.define do
issue_tracker_data { nil } issue_tracker_data { nil }
create_data { false } create_data { false }
after(:build) do |service| after(:build) do
IssueTrackerService.skip_callback(:validation, :before, :handle_properties) IssueTrackerService.skip_callback(:validation, :before, :handle_properties)
end end
......
...@@ -3,6 +3,6 @@ ...@@ -3,6 +3,6 @@
FactoryBot.define do FactoryBot.define do
factory :service_hook do factory :service_hook do
url { generate(:url) } url { generate(:url) }
service integration
end end
end end
...@@ -4,7 +4,7 @@ require 'spec_helper' ...@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe 'Admin visits service templates' do RSpec.describe 'Admin visits service templates' do
let(:admin) { create(:user, :admin) } let(:admin) { create(:user, :admin) }
let(:slack_service) { Service.for_template.find { |s| s.type == 'SlackService' } } let(:slack_service) { Integration.for_template.find { |s| s.type == 'SlackService' } }
before do before do
sign_in(admin) sign_in(admin)
......
...@@ -4,7 +4,7 @@ require 'spec_helper' ...@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe 'Profile > Chat' do RSpec.describe 'Profile > Chat' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:service) { create(:service) } let(:integration) { create(:service) }
before do before do
sign_in(user) sign_in(user)
...@@ -15,7 +15,7 @@ RSpec.describe 'Profile > Chat' do ...@@ -15,7 +15,7 @@ RSpec.describe 'Profile > Chat' do
{ team_id: 'T00', team_domain: 'my_chat_team', user_id: 'U01', user_name: 'my_chat_user' } { team_id: 'T00', team_domain: 'my_chat_team', user_id: 'U01', user_name: 'my_chat_user' }
end end
let!(:authorize_url) { ChatNames::AuthorizeUserService.new(service, params).execute } let!(:authorize_url) { ChatNames::AuthorizeUserService.new(integration, params).execute }
let(:authorize_path) { URI.parse(authorize_url).request_uri } let(:authorize_path) { URI.parse(authorize_url).request_uri }
before do before do
...@@ -60,7 +60,7 @@ RSpec.describe 'Profile > Chat' do ...@@ -60,7 +60,7 @@ RSpec.describe 'Profile > Chat' do
end end
describe 'visits chat accounts' do describe 'visits chat accounts' do
let!(:chat_name) { create(:chat_name, user: user, service: service) } let!(:chat_name) { create(:chat_name, user: user, integration: integration) }
before do before do
visit profile_chat_names_path visit profile_chat_names_path
......
...@@ -11,5 +11,5 @@ RSpec.describe GitlabSchema.types['ServiceType'] do ...@@ -11,5 +11,5 @@ RSpec.describe GitlabSchema.types['ServiceType'] do
end end
def available_services_enum def available_services_enum
::Service.available_services_types(include_dev: false).map(&:underscore).map(&:upcase) ::Integration.available_services_types(include_dev: false).map(&:underscore).map(&:upcase)
end end
...@@ -16,8 +16,8 @@ RSpec.describe Gitlab::Chat::Responder do ...@@ -16,8 +16,8 @@ RSpec.describe Gitlab::Chat::Responder do
it 'returns the responder for the build' do it 'returns the responder for the build' do
pipeline = create(:ci_pipeline) pipeline = create(:ci_pipeline)
build = create(:ci_build, pipeline: pipeline) build = create(:ci_build, pipeline: pipeline)
service = double(:service, chat_responder: Gitlab::Chat::Responder::Slack) integration = double(:integration, chat_responder: Gitlab::Chat::Responder::Slack)
chat_name = double(:chat_name, service: service) chat_name = double(:chat_name, integration: integration)
chat_data = double(:chat_data, chat_name: chat_name) chat_data = double(:chat_data, chat_name: chat_name)
allow(pipeline) allow(pipeline)
......
...@@ -137,11 +137,11 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService ...@@ -137,11 +137,11 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
it 'creates a Prometheus service' do it 'creates a Prometheus service' do
expect(result[:status]).to eq(:success) expect(result[:status]).to eq(:success)
services = result[:project].reload.services integrations = result[:project].reload.integrations
expect(services.count).to eq(1) expect(integrations.count).to eq(1)
# Ensures PrometheusService#self_monitoring_project? is true # Ensures PrometheusService#self_monitoring_project? is true
expect(services.first.allow_local_api_url?).to be_truthy expect(integrations.first.allow_local_api_url?).to be_truthy
end end
it 'creates an environment for the project' do it 'creates an environment for the project' do
......
...@@ -303,7 +303,7 @@ deploy_keys: ...@@ -303,7 +303,7 @@ deploy_keys:
- user - user
- deploy_keys_projects - deploy_keys_projects
- projects - projects
services: integrations:
- project - project
- service_hook - service_hook
- jira_tracker_data - jira_tracker_data
...@@ -356,7 +356,7 @@ project: ...@@ -356,7 +356,7 @@ project:
- management_clusters - management_clusters
- boards - boards
- last_event - last_event
- services - integrations
- campfire_service - campfire_service
- confluence_service - confluence_service
- datadog_service - datadog_service
......
...@@ -15,7 +15,7 @@ RSpec.describe Gitlab::Integrations::StiType do ...@@ -15,7 +15,7 @@ RSpec.describe Gitlab::Integrations::StiType do
it 'forms SQL SELECT statements correctly' do it 'forms SQL SELECT statements correctly' do
sql_statements = types.map do |type| sql_statements = types.map do |type|
Service.where(type: type).to_sql Integration.where(type: type).to_sql
end end
expect(sql_statements).to all(eq(expected_sql)) expect(sql_statements).to all(eq(expected_sql))
...@@ -31,7 +31,7 @@ RSpec.describe Gitlab::Integrations::StiType do ...@@ -31,7 +31,7 @@ RSpec.describe Gitlab::Integrations::StiType do
it 'forms SQL CREATE statements correctly' do it 'forms SQL CREATE statements correctly' do
sql_statements = types.map do |type| sql_statements = types.map do |type|
record = ActiveRecord::QueryRecorder.new { Service.insert({ type: type }) } record = ActiveRecord::QueryRecorder.new { Integration.insert({ type: type }) }
record.log.first record.log.first
end end
...@@ -69,7 +69,7 @@ RSpec.describe Gitlab::Integrations::StiType do ...@@ -69,7 +69,7 @@ RSpec.describe Gitlab::Integrations::StiType do
it 'forms SQL DELETE statements correctly' do it 'forms SQL DELETE statements correctly' do
sql_statements = types.map do |type| sql_statements = types.map do |type|
record = ActiveRecord::QueryRecorder.new { Service.delete_by(type: type) } record = ActiveRecord::QueryRecorder.new { Integration.delete_by(type: type) }
record.log.first record.log.first
end end
...@@ -93,7 +93,7 @@ RSpec.describe Gitlab::Integrations::StiType do ...@@ -93,7 +93,7 @@ RSpec.describe Gitlab::Integrations::StiType do
create(:service, type: 'AsanaService') create(:service, type: 'AsanaService')
types.each do |type| types.each do |type|
expect(Service.find_by(type: type)).to be_kind_of(Integrations::Asana) expect(Integration.find_by(type: type)).to be_kind_of(Integrations::Asana)
end end
end end
end end
......
...@@ -6,11 +6,11 @@ RSpec.describe ChatName do ...@@ -6,11 +6,11 @@ RSpec.describe ChatName do
let_it_be(:chat_name) { create(:chat_name) } let_it_be(:chat_name) { create(:chat_name) }
subject { chat_name } subject { chat_name }
it { is_expected.to belong_to(:service) } it { is_expected.to belong_to(:integration) }
it { is_expected.to belong_to(:user) } it { is_expected.to belong_to(:user) }
it { is_expected.to validate_presence_of(:user) } it { is_expected.to validate_presence_of(:user) }
it { is_expected.to validate_presence_of(:service) } it { is_expected.to validate_presence_of(:integration) }
it { is_expected.to validate_presence_of(:team_id) } it { is_expected.to validate_presence_of(:team_id) }
it { is_expected.to validate_presence_of(:chat_id) } it { is_expected.to validate_presence_of(:chat_id) }
...@@ -18,7 +18,7 @@ RSpec.describe ChatName do ...@@ -18,7 +18,7 @@ RSpec.describe ChatName do
it { is_expected.to validate_uniqueness_of(:chat_id).scoped_to(:service_id, :team_id) } it { is_expected.to validate_uniqueness_of(:chat_id).scoped_to(:service_id, :team_id) }
it 'is removed when the project is deleted' do it 'is removed when the project is deleted' do
expect { subject.reload.service.project.delete }.to change { ChatName.count }.by(-1) expect { subject.reload.integration.project.delete }.to change { ChatName.count }.by(-1)
expect(ChatName.where(id: subject.id)).not_to exist expect(ChatName.where(id: subject.id)).not_to exist
end end
......
...@@ -4697,8 +4697,8 @@ RSpec.describe Ci::Build do ...@@ -4697,8 +4697,8 @@ RSpec.describe Ci::Build do
end end
it 'executes services' do it 'executes services' do
allow_next_found_instance_of(Service) do |service| allow_next_found_instance_of(Integration) do |integration|
expect(service).to receive(:async_execute) expect(integration).to receive(:async_execute)
end end
build.execute_hooks build.execute_hooks
...@@ -4711,8 +4711,8 @@ RSpec.describe Ci::Build do ...@@ -4711,8 +4711,8 @@ RSpec.describe Ci::Build do
end end
it 'does not execute services' do it 'does not execute services' do
allow_next_found_instance_of(Service) do |service| allow_next_found_instance_of(Integration) do |integration|
expect(service).not_to receive(:async_execute) expect(integration).not_to receive(:async_execute)
end end
build.execute_hooks build.execute_hooks
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Integration do RSpec.describe HasIntegrations do
let_it_be(:project_1) { create(:project) } let_it_be(:project_1) { create(:project) }
let_it_be(:project_2) { create(:project) } let_it_be(:project_2) { create(:project) }
let_it_be(:project_3) { create(:project) } let_it_be(:project_3) { create(:project) }
......
...@@ -28,7 +28,7 @@ RSpec.describe Group do ...@@ -28,7 +28,7 @@ RSpec.describe Group do
it { is_expected.to have_many(:container_repositories) } it { is_expected.to have_many(:container_repositories) }
it { is_expected.to have_many(:milestones) } it { is_expected.to have_many(:milestones) }
it { is_expected.to have_many(:group_deploy_keys) } it { is_expected.to have_many(:group_deploy_keys) }
it { is_expected.to have_many(:services) } it { is_expected.to have_many(:integrations) }
it { is_expected.to have_one(:dependency_proxy_setting) } it { is_expected.to have_one(:dependency_proxy_setting) }
it { is_expected.to have_many(:dependency_proxy_blobs) } it { is_expected.to have_many(:dependency_proxy_blobs) }
it { is_expected.to have_many(:dependency_proxy_manifests) } it { is_expected.to have_many(:dependency_proxy_manifests) }
......
...@@ -4,11 +4,11 @@ require 'spec_helper' ...@@ -4,11 +4,11 @@ require 'spec_helper'
RSpec.describe ServiceHook do RSpec.describe ServiceHook do
describe 'associations' do describe 'associations' do
it { is_expected.to belong_to :service } it { is_expected.to belong_to :integration }
end end
describe 'validations' do describe 'validations' do
it { is_expected.to validate_presence_of(:service) } it { is_expected.to validate_presence_of(:integration) }
end end
describe 'execute' do describe 'execute' do
......
...@@ -138,8 +138,8 @@ RSpec.describe DataFields do ...@@ -138,8 +138,8 @@ RSpec.describe DataFields do
context 'when data are stored in both properties and data_fields' do context 'when data are stored in both properties and data_fields' do
let(:service) do let(:service) do
create(:jira_service, :without_properties_callback, active: false, properties: properties).tap do |service| create(:jira_service, :without_properties_callback, active: false, properties: properties).tap do |integration|
create(:jira_tracker_data, properties.merge(service: service)) create(:jira_tracker_data, properties.merge(integration: integration))
end end
end end
......
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe IssueTrackerData do RSpec.describe IssueTrackerData do
let(:service) { create(:custom_issue_tracker_service, active: false, properties: {}) } describe 'associations' do
it { is_expected.to belong_to :integration }
describe 'Associations' do
it { is_expected.to belong_to :service }
end end
end end
This diff is collapsed.
This diff is collapsed.
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