Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-02-22 03:14:19 +00:00
parent 6fded6a0b7
commit e4011eb845
44 changed files with 256 additions and 268 deletions

View File

@ -1 +1 @@
1c364e717ce8fdc4a6603f7369756785c146c898
ad76c4bd99833148140d5c08b7258363e5163b9c

View File

@ -10,9 +10,20 @@ module Types
# https://gitlab.com/gitlab-org/gitlab/-/issues/213088
field :type, GraphQL::Types::String, null: true,
description: 'Class name of the service.'
field :service_type, ::Types::Projects::ServiceTypeEnum, null: true,
description: 'Type of the service.'
field :active, GraphQL::Types::Boolean, null: true,
description: 'Indicates if the service is active.'
def type
enum = ::Types::Projects::ServiceTypeEnum.coerce_result(service_type, context)
enum.downcase.camelize
end
def service_type
object.type
end
definition_methods do
def resolve_type(object, context)
if object.is_a?(::Integrations::Jira)

View File

@ -8,7 +8,7 @@ module Types
class << self
private
def type_description(type)
def type_description(name, type)
"#{type} type"
end
end
@ -16,8 +16,10 @@ module Types
# This prepend must stay here because the dynamic block below depends on it.
prepend_mod # rubocop: disable Cop/InjectEnterpriseEditionModule
::Integration.available_integration_types(include_dev: false).each do |type|
value type.underscore.upcase, value: type, description: type_description(type)
::Integration.available_integration_names(include_dev: false).each do |name|
type = "#{name.camelize}Service"
domain_value = Integration.integration_name_to_type(name)
value type.underscore.upcase, value: domain_value, description: type_description(name, type)
end
end
end

View File

@ -12,6 +12,11 @@ class Integration < ApplicationRecord
include IgnorableColumns
ignore_column :template, remove_with: '15.0', remove_after: '2022-04-22'
ignore_column :type, remove_with: '15.0', remove_after: '2022-04-22'
UnknownType = Class.new(StandardError)
self.inheritance_column = :type_new
INTEGRATION_NAMES = %w[
asana assembla bamboo bugzilla buildkite campfire confluence custom_issue_tracker datadog discord
@ -44,7 +49,7 @@ class Integration < ApplicationRecord
serialize :properties, JSON # rubocop:disable Cop/ActiveRecordSerialize
attribute :type, Gitlab::Integrations::StiType.new
alias_attribute :type, :type_new
default_value_for :active, false
default_value_for :alert_events, true
@ -79,9 +84,10 @@ class Integration < ApplicationRecord
validate :validate_belongs_to_project_or_group
scope :external_issue_trackers, -> { where(category: 'issue_tracker').active }
scope :external_wikis, -> { where(type: 'ExternalWikiService').active }
scope :by_name, ->(name) { by_type(integration_name_to_type(name)) }
scope :external_wikis, -> { by_name(:external_wiki).active }
scope :active, -> { where(active: true) }
scope :by_type, -> (type) { where(type: type) }
scope :by_type, ->(type) { where(type: type) } # INTERNAL USE ONLY: use by_name instead
scope :by_active_flag, -> (flag) { where(active: flag) }
scope :inherit_from_id, -> (id) { where(inherit_from_id: id) }
scope :with_default_settings, -> { where.not(inherit_from_id: nil) }
@ -231,7 +237,7 @@ class Integration < ApplicationRecord
end
# Returns a list of available integration types.
# Example: ["AsanaService", ...]
# Example: ["Integrations::Asana", ...]
def self.available_integration_types(include_project_specific: true, include_dev: true)
available_integration_names(include_project_specific: include_project_specific, include_dev: include_dev).map do
integration_name_to_type(_1)
@ -239,22 +245,27 @@ class Integration < ApplicationRecord
end
# Returns the model for the given integration name.
# Example: "asana" => Integrations::Asana
# Example: :asana => Integrations::Asana
def self.integration_name_to_model(name)
type = integration_name_to_type(name)
integration_type_to_model(type)
end
# Returns the STI type for the given integration name.
# Example: "asana" => "AsanaService"
# Example: "asana" => "Integrations::Asana"
def self.integration_name_to_type(name)
"#{name}_service".camelize
name = name.to_s
if available_integration_names.exclude?(name)
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(UnknownType.new(name.inspect))
else
"Integrations::#{name.camelize}"
end
end
# Returns the model for the given STI type.
# Example: "AsanaService" => Integrations::Asana
# Example: "Integrations::Asana" => Integrations::Asana
def self.integration_type_to_model(type)
Gitlab::Integrations::StiType.new.cast(type).constantize
type.constantize
end
private_class_method :integration_type_to_model
@ -303,7 +314,7 @@ class Integration < ApplicationRecord
from_union([
active.where(instance: true),
active.where(group_id: group_ids, inherit_from_id: nil)
]).order(Arel.sql("type ASC, array_position(#{array}::bigint[], #{table_name}.group_id), instance DESC")).group_by(&:type).each do |type, records|
]).order(Arel.sql("type_new ASC, array_position(#{array}::bigint[], #{table_name}.group_id), instance DESC")).group_by(&:type).each do |type, records|
build_from_integration(records.first, association => scope.id).save
end
end
@ -380,8 +391,10 @@ class Integration < ApplicationRecord
%w[active]
end
# return a hash of columns => values suitable for passing to insert_all
def to_integration_hash
as_json(methods: :type, except: %w[id instance project_id group_id])
column = self.class.attribute_aliases.fetch('type', 'type')
as_json(except: %w[id instance project_id group_id]).merge(column => type)
end
def to_data_fields_hash

View File

@ -1,8 +0,0 @@
---
name: roadmap_settings
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78626
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350830
milestone: '14.8'
type: development
group: group::product planning
default_enabled: true

View File

@ -185,7 +185,7 @@ production: &base
## Reply by email
# Allow users to comment on issues and merge requests by replying to notification emails.
# For documentation on how to set this up, see http://doc.gitlab.com/ce/administration/reply_by_email.html
# For documentation on how to set this up, see https://docs.gitlab.com/ee/administration/reply_by_email.html
incoming_email:
enabled: false

View File

@ -8726,6 +8726,7 @@ An emoji awarded by a user.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="baseserviceactive"></a>`active` | [`Boolean`](#boolean) | Indicates if the service is active. |
| <a id="baseserviceservicetype"></a>`serviceType` | [`ServiceType`](#servicetype) | Type of the service. |
| <a id="baseservicetype"></a>`type` | [`String`](#string) | Class name of the service. |
### `Blob`
@ -12028,6 +12029,7 @@ Represents an iteration cadence.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="jiraserviceactive"></a>`active` | [`Boolean`](#boolean) | Indicates if the service is active. |
| <a id="jiraserviceservicetype"></a>`serviceType` | [`ServiceType`](#servicetype) | Type of the service. |
| <a id="jiraservicetype"></a>`type` | [`String`](#string) | Class name of the service. |
#### Fields with arguments
@ -19284,6 +19286,7 @@ Implementations:
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="serviceactive"></a>`active` | [`Boolean`](#boolean) | Indicates if the service is active. |
| <a id="serviceservicetype"></a>`serviceType` | [`ServiceType`](#servicetype) | Type of the service. |
| <a id="servicetype"></a>`type` | [`String`](#string) | Class name of the service. |
#### `TimeboxReportInterface`

View File

@ -349,7 +349,7 @@ Component statuses are linked to configuration documentation for each component.
| [GitLab Exporter](#gitlab-exporter) | Generates a variety of GitLab metrics | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | CE & EE |
| [GitLab Geo Node](#gitlab-geo) | Geographically distributed GitLab nodes | ⚙ | ⚙ | ❌ | ❌ | ✅ | ❌ | ⚙ | EE Only |
| [GitLab Pages](#gitlab-pages) | Hosts static websites | ⚙ | ⚙ | ❌ | ❌ | ✅ | ⚙ | ⚙ | CE & EE |
| [GitLab Agent](#gitlab-agent) | Integrate Kubernetes clusters in a cloud-native way | ⚙ | ⚙ | ⚙ | ❌ | ❌ | ⤓ | ⚙ | EE Only |
| [GitLab agent](#gitlab-agent) | Integrate Kubernetes clusters in a cloud-native way | ⚙ | ⚙ | ⚙ | ❌ | ❌ | ⤓ | ⚙ | EE Only |
| [GitLab self-monitoring: Alertmanager](#alertmanager) | Deduplicates, groups, and routes alerts from Prometheus | ⚙ | ⚙ | ✅ | ⚙ | ✅ | ❌ | ❌ | CE & EE |
| [GitLab self-monitoring: Grafana](#grafana) | Metrics dashboard | ✅ | ✅ | ⚙ | ⤓ | ✅ | ❌ | ⚙ | CE & EE |
| [GitLab self-monitoring: Jaeger](#jaeger) | View traces generated by the GitLab instance | ❌ | ⚙ | ⚙ | ❌ | ❌ | ⤓ | ⚙ | CE & EE |
@ -499,14 +499,14 @@ Geo is a premium feature built to help speed up the development of distributed t
GitLab Exporter is a process designed in house that allows us to export metrics about GitLab application internals to Prometheus. You can read more [in the project's README](https://gitlab.com/gitlab-org/gitlab-exporter).
#### GitLab Agent
#### GitLab agent
- [Project page](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent)
- Configuration:
- [Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template)
- [Charts](https://docs.gitlab.com/charts/charts/gitlab/kas/index.html)
The [GitLab Agent](../user/clusters/agent/index.md) is an active in-cluster
The [GitLab agent](../user/clusters/agent/index.md) is an active in-cluster
component for solving GitLab and Kubernetes integration tasks in a secure and
cloud-native way.

View File

@ -113,7 +113,7 @@ The remaining records are truncated when this limit is reached.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `compliance_violations_report`.
The feature is not ready for production use.
On GitLab.com, this feature is not available. This feature is not ready for production use.
Merge request violations provide a view of all the [separation of duties](#approval-status-and-separation-of-duties) compliance violations
that exist in projects in a specific group. For each separation of duties compliance violation, you can see:

View File

@ -46,19 +46,16 @@ the immediate parent group.
### Namespaces
In GitLab, a namespace is a unique name and URL for a user, a group, or subgroup.
- `http://gitlab.example.com/username`
- `http://gitlab.example.com/groupname`
- `http://gitlab.example.com/groupname/subgroup_name`
In GitLab, a namespace is a unique name for a user, a group, or subgroup under
which a project can be created.
For example, consider a user named Alex:
1. Alex creates an account with the username `alex`: `https://gitlab.example.com/alex`
1. Alex creates a group for their team with the group name `alex-team`.
The group and its projects are available at: `https://gitlab.example.com/alex-team`
1. Alex creates a subgroup of `alex-team` with the subgroup name `marketing`.
The subgroup and its projects are available at: `https://gitlab.example.com/alex-team/marketing`
| GitLab URL | Namespace |
| ---------- | --------- |
| Alex creates an account with the username `alex`: `https://gitlab.example.com/alex`. | The namespace in this case is `alex`. |
| Alex creates a group for their team with the group name `alex-team`. The group and its projects are available at: `https://gitlab.example.com/alex-team`. | The namespace in this cases is `alex-team`. |
| Alex creates a subgroup of `alex-team` with the subgroup name `marketing`. The subgroup and its projects are available at: `https://gitlab.example.com/alex-team/marketing`. | The namespace in this case is `alex-team/marketing`. |
## Create a group

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -47,10 +47,6 @@ Filtering roadmaps by milestone might not be available to you. Check the **versi
When you want to explore a roadmap, there are several ways to make it easier by sorting epics or
filtering them by what's important for you.
A dropdown list lets you show only open or closed epics. By default, all epics are shown.
![epics state dropdown list](img/epics_state_dropdown_v14_3.png)
You can sort epics in the Roadmap view by:
- Start date
@ -74,11 +70,8 @@ Roadmaps can also be [visualized inside an epic](../epics/index.md#roadmap-in-ep
### Roadmap settings
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345158) in GitLab 14.8 [with a flag](../../../administration/feature_flags.md) named `roadmap_settings`. Enabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `roadmap_settings`.
On GitLab.com, this feature is available but can be configured by GitLab.com administrators only.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345158) in GitLab 14.8 [with a flag](../../../administration/feature_flags.md) named `roadmap_settings`. Enabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/350830) in GitLab 14.9. Feature flag `roadmap_settings`removed.
When you enable the roadmap settings sidebar, you can use it to refine epics shown in the roadmap.

View File

@ -214,6 +214,35 @@ we recommend the ["Use the OneLogin SAML Test Connector" documentation](https://
Recommended `NameID` value: `OneLogin ID`.
### Change the SAML app
To change the SAML app used for sign in:
- If the NameID is not identical in both the existing and new SAML apps, users must:
1. [Unlink the current SAML identity](#unlinking-accounts).
1. [Link their identity](#user-access-and-management) to the new SAML app.
- If the NameID is identical, no change is required.
### Migrate to a different SAML provider
You can migrate to a different SAML provider. During the migration process users will not be able to access any of the SAML groups.
To mitigate this, you can disable [SSO enforcement](#sso-enforcement).
To migrate SAML providers:
1. [Configure](#configure-your-identity-provider) the group with the new identity provider SAML app.
1. Ask users to [unlink their account from the group](#unlinking-accounts).
1. Ask users to [link their account to the new SAML app](#linking-saml-to-your-existing-gitlabcom-account).
### Change email domains
To migrate users to a new email domain, users must:
1. Add their new email as the primary email to their accounts and verify it.
1. [Unlink their account from the group](#unlinking-accounts).
1. [Link their account to the group](#linking-saml-to-your-existing-gitlabcom-account).
1. (Optional) Remove their old email from the account.
## User access and management
> [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/268142) in GitLab 13.7.
@ -610,12 +639,6 @@ Alternatively, when users need to [link SAML to their existing GitLab.com accoun
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| As mentioned in the [NameID](#nameid) section, if the NameID changes for any user, the user can be locked out. This is a common problem when an email address is used as the identifier. | Follow the steps outlined in the ["SAML authentication failed: User has already been taken"](#message-saml-authentication-failed-user-has-already-been-taken) section. |
### I need to change my SAML app
If the NameID is identical in both SAML apps, then no change is required.
Otherwise, to change the SAML app used for sign in, users need to [unlink the current SAML identity](#unlinking-accounts) and then [link their identity](#user-access-and-management) to the new SAML app.
### I need additional information to configure my identity provider
Many SAML terms can vary between providers. It is possible that the information you are looking for is listed under another name.

View File

@ -244,7 +244,7 @@ It is important not to update these to incorrect values, since this causes users
### I need to change my SCIM app
Individual users can follow the instructions in the ["SAML authentication failed: User has already been taken"](index.md#i-need-to-change-my-saml-app) section.
Individual users can follow the instructions in the ["SAML authentication failed: User has already been taken"](index.md#change-the-saml-app) section.
Alternatively, users can be removed from the SCIM app which de-links all removed users. Sync can then be turned on for the new SCIM app to [link existing users](#user-access-and-linking-setup).

View File

@ -8,10 +8,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
The [certificate-based Kubernetes integration with GitLab](../index.md)
was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8)
in GitLab 14.5. To connect your clusters, use the [GitLab Agent](../../../clusters/agent/index.md).
in GitLab 14.5. To connect your clusters, use the [GitLab agent](../../../clusters/agent/index.md).
<!-- TBA: (We need to resolve https://gitlab.com/gitlab-org/gitlab/-/issues/343660 before adding this line)
If you don't have a cluster yet, create one and connect it to GitLab through the Agent.
If you don't have a cluster yet, create one and connect it to GitLab through the agent.
You can also create a new cluster from GitLab using [Infrastructure as Code](../../iac/index.md#create-a-new-cluster-through-iac).
-->

View File

@ -79,8 +79,8 @@ contains other variables that you can override according to your needs:
- `TF_VAR_cluster_version`: Set the version of Kubernetes.
- `TF_VAR_instance_type`: Set the instance type for the Kubernetes nodes.
- `TF_VAR_instance_count`: Set the number of Kubernetes nodes.
- `TF_VAR_agent_version`: Set the version of the GitLab Agent.
- `TF_VAR_agent_namespace`: Set the Kubernetes namespace for the GitLab Agent.
- `TF_VAR_agent_version`: Set the version of the GitLab agent.
- `TF_VAR_agent_namespace`: Set the Kubernetes namespace for the GitLab agent.
View the [AWS Terraform provider](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) and the [Kubernetes Terraform provider](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs) documentation for further resource options.

View File

@ -11,9 +11,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
The process described on this page uses cluster certificates to connect the
new cluster to GitLab, [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
You can still create a cluster and then connect it to GitLab through the [Agent](../index.md).
You can still create a cluster and then connect it to GitLab through the [agent](../index.md).
[An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/343660)
to migrate this functionality to the [Agent](../index.md).
to migrate this functionality to the [agent](../index.md).
Learn how to create a new cluster on Google Kubernetes Engine (GKE) through
[Infrastructure as Code (IaC)](../../index.md).

View File

@ -9,10 +9,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0.
An inventory object is a `ConfigMap` object for keeping track of the set of objects applied to a cluster.
When you remove objects from a manifest repository, the Agent uses a corresponding inventory object to
When you remove objects from a manifest repository, the agent uses a corresponding inventory object to
prune (delete) objects from the cluster.
The Agent creates an inventory object for each manifest project specified in the
The agent creates an inventory object for each manifest project specified in the
`gitops.manifest_projects` configuration section. The inventory object has to be stored somewhere in the cluster.
The default behavior is:
@ -20,10 +20,10 @@ The default behavior is:
explicitly, the inventory object is stored in the `default` namespace.
- The `name` is generated from the numeric project ID of the manifest project and the numeric agent ID.
This way, the Agent constructs the name and location where the inventory object is
This way, the agent constructs the name and location where the inventory object is
stored in the cluster.
The Agent cannot locate the existing inventory object if you:
The agent cannot locate the existing inventory object if you:
- Change `gitops.manifest_projects[].default_namespace` parameter.
- Move manifests into another project.
@ -57,13 +57,13 @@ metadata:
## Using GitOps with pre-existing Kubernetes objects
The Agent treats manifest files in the manifest repository as the source of truth. When it applies
The agent treats manifest files in the manifest repository as the source of truth. When it applies
objects from the files to the cluster, it tracks them in an inventory object. If an object already exists,
The Agent behaves differently based on the `gitops.manifest_projects[].inventory_policy` configuration.
The agent behaves differently based on the `gitops.manifest_projects[].inventory_policy` configuration.
Check the table below with the available options and when to use them.
`inventory_policy` value | Description |
------------------------ | ------------------------------------------------------------------------------------------- |
`must_match` | This is the default policy. A live object must have the `config.k8s.io/owning-inventory` annotation set to the same value as the `cli-utils.sigs.k8s.io/inventory-id` label on the corresponding inventory object to be updated. Object is not updated and an error is reported if the values don't match or the object doesn't have the annotation. |
`adopt_if_no_inventory` | This mode allows to "adopt" an object if it doesn't have the `config.k8s.io/owning-inventory` annotation. Use this mode if you want to start managing existing objects using the GitOps feature. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. |
`adopt_all` | This mode allows to "adopt" an object even if it has the `config.k8s.io/owning-inventory` annotation set to a different value. This mode can be useful if you want to migrate a set of objects from one agent to another one or from some other tool to the Agent. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. |
`adopt_all` | This mode allows to "adopt" an object even if it has the `config.k8s.io/owning-inventory` annotation set to a different value. This mode can be useful if you want to migrate a set of objects from one agent to another one or from some other tool to the agent. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. |

View File

@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. To connect clusters to GitLab,
use the [GitLab Agent](../../clusters/agent/index.md).
use the [GitLab agent](../../clusters/agent/index.md).
Similar to [project-level](../../project/clusters/index.md)
and [group-level](../../group/clusters/index.md) Kubernetes clusters,

View File

@ -19,7 +19,7 @@ Kubernetes Service (EKS).
## Connect an existing EKS cluster
If you already have an EKS cluster and want to connect it to GitLab,
use the [GitLab Agent](../../clusters/agent/index.md).
use the [GitLab agent](../../clusters/agent/index.md).
## Create a new EKS cluster

View File

@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
To connect your cluster to GitLab, use the [GitLab Agent](../../clusters/agent/index.md)
To connect your cluster to GitLab, use the [GitLab agent](../../clusters/agent/index.md)
instead.
If you have an existing Kubernetes cluster, you can add it to a project, group,

View File

@ -19,7 +19,7 @@ hosted on Google Kubernetes Engine (GKE).
## Connect an existing GKE cluster
If you already have a GKE cluster and want to connect it to GitLab,
use the [GitLab Agent](../../clusters/agent/index.md).
use the [GitLab agent](../../clusters/agent/index.md).
## Create a new GKE cluster from GitLab

View File

@ -49,7 +49,7 @@ supports connecting existing clusters using the certificate-based connection met
## Add existing cluster
As of GitLab 14.0, use the [GitLab Agent](../../clusters/agent/index.md)
As of GitLab 14.0, use the [GitLab agent](../../clusters/agent/index.md)
to connect your cluster to GitLab.
Alternatively, you can [add an existing cluster](add_existing_cluster.md)
@ -57,7 +57,7 @@ through the certificate-based method, but we don't recommend using this method f
## Configure your cluster
As of GitLab 14.0, use the [GitLab Agent](../../clusters/agent/index.md)
As of GitLab 14.0, use the [GitLab agent](../../clusters/agent/index.md)
to configure your cluster.
## Disable a cluster

View File

@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
To connect your cluster to GitLab, use the [GitLab Agent](../../clusters/agent/index.md)
To connect your cluster to GitLab, use the [GitLab agent](../../clusters/agent/index.md)
instead.
When creating a cluster in GitLab, you are asked if you would like to create either:

View File

@ -10,8 +10,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
To connect your cluster to GitLab, use the [GitLab Agent](../../clusters/agent/index.md).
To deploy with the Agent, use the [CI/CD Tunnel](../../clusters/agent/ci_cd_tunnel.md).
To connect your cluster to GitLab, use the [GitLab agent](../../clusters/agent/index.md).
To deploy with the agent, use the [CI/CD workflow](../../clusters/agent/ci_cd_tunnel.md).
A Kubernetes cluster can be the destination for a deployment job. If

View File

@ -12,7 +12,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
To connect your cluster to GitLab, use the [GitLab Agent](../../../user/clusters/agent/index.md).
To connect your cluster to GitLab, use the [GitLab agent](../../../user/clusters/agent/index.md).
To manage applications, use the [Cluster Project Management Template](../../../user/clusters/management_project_template.md).
You can choose to allow GitLab to manage your cluster for you. If your cluster

View File

@ -12,7 +12,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8)
in GitLab 14.5. To connect clusters to GitLab, use the
[GitLab Agent](../../clusters/agent/index.md).
[GitLab agent](../../clusters/agent/index.md).
[Project-level](../../infrastructure/clusters/connect/index.md#cluster-levels-deprecated) Kubernetes clusters
allow you to connect a Kubernetes cluster to a project in GitLab.

View File

@ -13,7 +13,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
Using multiple Kubernetes clusters for a single project **with cluster
certificates** was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
To connect clusters to GitLab, use the [GitLab Agent](../../../user/clusters/agent/index.md).
To connect clusters to GitLab, use the [GitLab agent](../../../user/clusters/agent/index.md).
You can associate more than one Kubernetes cluster to your
project. That way you can have different clusters for different environments,

View File

@ -20,7 +20,7 @@ type: howto, reference
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
[An epic exists](https://gitlab.com/groups/gitlab-org/-/epics/2493)
to add this functionality to the [Agent](../index.md).
to add this functionality to the [agent](../index.md).
GitLab deploy boards offer a consolidated view of the current health and
status of each CI [environment](../../ci/environments/index.md) running on [Kubernetes](https://kubernetes.io), displaying the status

View File

@ -3519,9 +3519,6 @@ msgstr ""
msgid "All environments"
msgstr ""
msgid "All epics"
msgstr ""
msgid "All groups and projects"
msgstr ""
@ -7576,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
msgid "Closed epics"
msgstr ""
msgid "Closed issues"
msgstr ""
@ -25608,9 +25602,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
msgid "Open epics"
msgstr ""
msgid "Open errors"
msgstr ""
@ -29885,9 +29876,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
msgid "Quarters"
msgstr ""
msgid "Query"
msgstr ""

View File

@ -2,7 +2,11 @@
module QA
RSpec.describe 'Create' do
describe 'Open a fork in Web IDE' do
describe 'Open a fork in Web IDE', quarantine: {
only: { subdomain: %i[canary production] },
issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/347247",
type: :flaky
} do
let(:parent_project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'parent-project'

View File

@ -12,6 +12,16 @@ FactoryBot.define do
issue_tracker
end
factory :jenkins_integration, class: 'Integrations::Jenkins' do
project
active { true }
type { 'Integrations::Jenkins' }
jenkins_url { 'http://jenkins.example.com/' }
project_name { 'my-project' }
username { 'jenkings-user' }
password { 'passw0rd' }
end
factory :datadog_integration, class: 'Integrations::Datadog' do
project
active { true }
@ -20,7 +30,7 @@ FactoryBot.define do
factory :emails_on_push_integration, class: 'Integrations::EmailsOnPush' do
project
type { 'EmailsOnPushService' }
type { 'Integrations::EmailsOnPush' }
active { true }
push_events { true }
tag_push_events { true }
@ -54,7 +64,7 @@ FactoryBot.define do
factory :jira_integration, class: 'Integrations::Jira' do
project
active { true }
type { 'JiraService' }
type { 'Integrations::Jira' }
transient do
create_data { true }
@ -88,7 +98,7 @@ FactoryBot.define do
factory :zentao_integration, class: 'Integrations::Zentao' do
project
active { true }
type { 'ZentaoService' }
type { 'Integrations::Zentao' }
transient do
create_data { true }
@ -167,7 +177,7 @@ FactoryBot.define do
factory :external_wiki_integration, class: 'Integrations::ExternalWiki' do
project
type { 'ExternalWikiService' }
type { 'Integrations::ExternalWiki' }
active { true }
external_wiki_url { 'http://external-wiki-url.com' }
end
@ -178,24 +188,39 @@ FactoryBot.define do
password { 'my-secret-password' }
end
trait :chat_notification do
webhook { 'https://example.com/webhook' }
end
trait :inactive do
active { false }
end
factory :mattermost_integration, class: 'Integrations::Mattermost' do
chat_notification
project
type { 'Integrations::Mattermost' }
active { true }
end
# avoids conflict with slack_integration factory
factory :integrations_slack, class: 'Integrations::Slack' do
chat_notification
project
active { true }
webhook { 'https://slack.service.url' }
type { 'SlackService' }
type { 'Integrations::Slack' }
end
factory :slack_slash_commands_integration, class: 'Integrations::SlackSlashCommands' do
project
active { true }
type { 'SlackSlashCommandsService' }
type { 'Integrations::SlackSlashCommands' }
end
factory :pipelines_email_integration, class: 'Integrations::PipelinesEmail' do
project
active { true }
type { 'PipelinesEmailService' }
type { 'Integrations::PipelinesEmail' }
recipients { 'test@example.com' }
end

View File

@ -5,8 +5,7 @@ FactoryBot.define do
skip_create # non-model factories (i.e. without #save)
initialize_with do
projects = create_list(:project, 3)
projects << create(:project, :repository)
projects = create_list(:project, 4, :repository)
group = create(:group)
create(:board, project: projects[0])
create(:jira_integration, project: projects[0])
@ -19,16 +18,21 @@ FactoryBot.define do
create(:jira_import_state, :finished, project: projects[1], label: jira_label, imported_issues_count: 3)
create(:jira_import_state, :scheduled, project: projects[1], label: jira_label)
create(:prometheus_integration, project: projects[1])
create(:integration, project: projects[1], type: 'JenkinsService', active: true)
create(:integration, project: projects[0], type: 'SlackSlashCommandsService', active: true)
create(:integration, project: projects[1], type: 'SlackService', active: true)
create(:integration, project: projects[2], type: 'SlackService', active: true)
create(:integration, project: projects[2], type: 'MattermostService', active: false)
create(:integration, group: group, project: nil, type: 'MattermostService', active: true)
mattermost_instance = create(:integration, :instance, type: 'MattermostService', active: true)
create(:integration, project: projects[1], type: 'MattermostService', active: true, inherit_from_id: mattermost_instance.id)
create(:integration, group: group, project: nil, type: 'SlackService', active: true, inherit_from_id: mattermost_instance.id)
create(:integration, project: projects[2], type: 'CustomIssueTrackerService', active: true)
create(:jenkins_integration, project: projects[1])
# slack
create(:slack_slash_commands_integration, project: projects[0])
create(:integrations_slack, project: projects[1])
create(:integrations_slack, project: projects[2])
# mattermost
create(:mattermost_integration, project: projects[2], active: false)
create(:mattermost_integration, group: group, project: nil)
mattermost_instance = create(:mattermost_integration, :instance)
create(:mattermost_integration, project: projects[1], inherit_from_id: mattermost_instance.id)
create(:integrations_slack, group: group, project: nil, active: true, inherit_from_id: mattermost_instance.id)
create(:custom_issue_tracker_integration, project: projects[2], active: true)
create(:project_error_tracking_setting, project: projects[0])
create(:project_error_tracking_setting, project: projects[1], enabled: false)
alert_bot_issues = create_list(:incident, 2, project: projects[0], author: User.alert_bot)

View File

@ -96,10 +96,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
context 'view merge request with external CI service' do
before do
create(:integration, project: project,
active: true,
type: 'DroneCiService',
category: 'ci')
create(:drone_ci_integration, project: project)
visit project_merge_request_path(project, merge_request)
end

View File

@ -6,7 +6,7 @@ RSpec.describe GitlabSchema.types['BaseService'] do
specify { expect(described_class.graphql_name).to eq('BaseService') }
it 'has basic expected fields' do
expect(described_class).to have_graphql_fields(:type, :active)
expect(described_class).to have_graphql_fields(:type, :active, :service_type)
end
specify { expect(described_class).to require_graphql_authorizations(:admin_project) }

View File

@ -6,7 +6,7 @@ RSpec.describe GitlabSchema.types['JiraService'] do
specify { expect(described_class.graphql_name).to eq('JiraService') }
it 'has basic expected fields' do
expect(described_class).to have_graphql_fields(:type, :active, :projects)
expect(described_class).to have_graphql_fields(:type, :active, :projects, :service_type)
end
specify { expect(described_class).to require_graphql_authorizations(:admin_project) }

View File

@ -4,10 +4,52 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['ServiceType'] do
it 'exposes all the existing project services' do
expect(described_class.values.keys).to match_array(available_services_enum)
expect(described_class.values.keys).to include(*core_service_enums)
end
def available_services_enum
::Integration.available_integration_types(include_dev: false).map(&:underscore).map(&:upcase)
def core_service_enums
%w[
ASANA_SERVICE
ASSEMBLA_SERVICE
BAMBOO_SERVICE
BUGZILLA_SERVICE
BUILDKITE_SERVICE
CAMPFIRE_SERVICE
CONFLUENCE_SERVICE
CUSTOM_ISSUE_TRACKER_SERVICE
DATADOG_SERVICE
DISCORD_SERVICE
DRONE_CI_SERVICE
EMAILS_ON_PUSH_SERVICE
EWM_SERVICE
EXTERNAL_WIKI_SERVICE
FLOWDOCK_SERVICE
HANGOUTS_CHAT_SERVICE
IRKER_SERVICE
JENKINS_SERVICE
JIRA_SERVICE
MATTERMOST_SERVICE
MATTERMOST_SLASH_COMMANDS_SERVICE
MICROSOFT_TEAMS_SERVICE
PACKAGIST_SERVICE
PIPELINES_EMAIL_SERVICE
PIVOTALTRACKER_SERVICE
PROMETHEUS_SERVICE
PUSHOVER_SERVICE
REDMINE_SERVICE
SHIMO_SERVICE
SLACK_SERVICE
SLACK_SLASH_COMMANDS_SERVICE
TEAMCITY_SERVICE
UNIFY_CIRCUIT_SERVICE
WEBEX_TEAMS_SERVICE
YOUTRACK_SERVICE
ZENTAO_SERVICE
]
end
it 'coerces values correctly' do
integration = build(:jenkins_integration)
expect(described_class.coerce_isolated_result(integration.type)).to eq 'JENKINS_SERVICE'
end
end

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Types::Projects::ServiceType do
specify { expect(described_class).to have_graphql_fields(:type, :active) }
specify { expect(described_class).to have_graphql_fields(:type, :service_type, :active) }
describe ".resolve_type" do
it 'resolves the corresponding type for objects' do

View File

@ -1,114 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Integrations::StiType do
let(:types) { ['AsanaService', 'Integrations::Asana', Integrations::Asana] }
describe '#serialize' do
context 'SQL SELECT' do
let(:expected_sql) do
<<~SQL.strip
FROM "integrations" WHERE "integrations"."type" = 'AsanaService'
SQL
end
it 'forms SQL SELECT statements correctly' do
sql_statements = types.map do |type|
Integration.where(type: type).to_sql
end
expect(sql_statements).to all(end_with(expected_sql))
end
end
context 'SQL CREATE' do
let(:expected_sql) do
<<~SQL.strip
INSERT INTO "integrations" ("type") VALUES ('AsanaService')
SQL
end
it 'forms SQL CREATE statements correctly' do
sql_statements = types.map do |type|
record = ActiveRecord::QueryRecorder.new { Integration.insert({ type: type }) }
record.log.first
end
expect(sql_statements).to all(include(expected_sql))
end
end
context 'SQL UPDATE' do
let(:expected_sql) do
<<~SQL.strip
UPDATE "integrations" SET "type" = 'AsanaService'
SQL
end
let_it_be(:integration) { create(:integration) }
it 'forms SQL UPDATE statements correctly' do
sql_statements = types.map do |type|
record = ActiveRecord::QueryRecorder.new { integration.update_column(:type, type) }
record.log.first
end
expect(sql_statements).to all(include(expected_sql))
end
end
context 'SQL DELETE' do
let(:expected_sql) do
<<~SQL.strip
DELETE FROM "integrations" WHERE "integrations"."type" = 'AsanaService'
SQL
end
it 'forms SQL DELETE statements correctly' do
sql_statements = types.map do |type|
record = ActiveRecord::QueryRecorder.new { Integration.delete_by(type: type) }
record.log.first
end
expect(sql_statements).to all(match(expected_sql))
end
end
end
describe '#deserialize' do
specify 'it deserializes type correctly', :aggregate_failures do
types.each do |type|
service = create(:integration, type: type)
expect(service.type).to eq('AsanaService')
end
end
end
describe '#cast' do
it 'casts type as model correctly', :aggregate_failures do
create(:integration, type: 'AsanaService')
types.each do |type|
expect(Integration.find_by(type: type)).to be_kind_of(Integrations::Asana)
end
end
end
describe '#changed?' do
it 'detects changes correctly', :aggregate_failures do
service = create(:integration, type: 'AsanaService')
types.each do |type|
service.type = type
expect(service).not_to be_changed
end
service.type = 'NewType'
expect(service).to be_changed
end
end
end

View File

@ -85,14 +85,14 @@ RSpec.describe Integration do
subject { described_class.by_type(type) }
context 'when type is "JiraService"' do
let(:type) { 'JiraService' }
context 'when type is "Integrations::JiraService"' do
let(:type) { 'Integrations::Jira' }
it { is_expected.to match_array([integration1, integration2]) }
end
context 'when type is "RedmineService"' do
let(:type) { 'RedmineService' }
context 'when type is "Integrations::Redmine"' do
let(:type) { 'Integrations::Redmine' }
it { is_expected.to match_array([integration3]) }
end
@ -103,7 +103,7 @@ RSpec.describe Integration do
let!(:integration2) { create(:jira_integration) }
it 'returns the right group integration' do
expect(described_class.for_group(group)).to match_array([integration1])
expect(described_class.for_group(group)).to contain_exactly(integration1)
end
end
@ -376,22 +376,24 @@ RSpec.describe Integration do
let_it_be(:instance_integration) { create(:jira_integration, :instance) }
it 'returns the instance integration' do
expect(described_class.default_integration('JiraService', project)).to eq(instance_integration)
expect(described_class.default_integration('Integrations::Jira', project)).to eq(instance_integration)
end
it 'returns nil for nonexistent integration type' do
expect(described_class.default_integration('HipchatService', project)).to eq(nil)
expect(described_class.default_integration('Integrations::Hipchat', project)).to eq(nil)
end
context 'with a group integration' do
let(:integration_name) { 'Integrations::Jira' }
let_it_be(:group_integration) { create(:jira_integration, group_id: group.id, project_id: nil) }
it 'returns the group integration for a project' do
expect(described_class.default_integration('JiraService', project)).to eq(group_integration)
expect(described_class.default_integration(integration_name, project)).to eq(group_integration)
end
it 'returns the instance integration for a group' do
expect(described_class.default_integration('JiraService', group)).to eq(instance_integration)
expect(described_class.default_integration(integration_name, group)).to eq(instance_integration)
end
context 'with a subgroup' do
@ -400,18 +402,18 @@ RSpec.describe Integration do
let!(:project) { create(:project, group: subgroup) }
it 'returns the closest group integration for a project' do
expect(described_class.default_integration('JiraService', project)).to eq(group_integration)
expect(described_class.default_integration(integration_name, project)).to eq(group_integration)
end
it 'returns the closest group integration for a subgroup' do
expect(described_class.default_integration('JiraService', subgroup)).to eq(group_integration)
expect(described_class.default_integration(integration_name, subgroup)).to eq(group_integration)
end
context 'having a integration with custom settings' do
let!(:subgroup_integration) { create(:jira_integration, group_id: subgroup.id, project_id: nil) }
it 'returns the closest group integration for a project' do
expect(described_class.default_integration('JiraService', project)).to eq(subgroup_integration)
expect(described_class.default_integration(integration_name, project)).to eq(subgroup_integration)
end
end
@ -419,7 +421,7 @@ RSpec.describe Integration do
let!(:subgroup_integration) { create(:jira_integration, group_id: subgroup.id, project_id: nil, inherit_from_id: group_integration.id) }
it 'returns the closest group integration which does not inherit from its parent for a project' do
expect(described_class.default_integration('JiraService', project)).to eq(group_integration)
expect(described_class.default_integration(integration_name, project)).to eq(group_integration)
end
end
end
@ -556,19 +558,26 @@ RSpec.describe Integration do
end
end
describe '.integration_name_to_model' do
it 'returns the model for the given integration name' do
expect(described_class.integration_name_to_model('asana')).to eq(Integrations::Asana)
describe '.integration_name_to_type' do
it 'handles a simple case' do
expect(described_class.integration_name_to_type(:asana)).to eq 'Integrations::Asana'
end
it 'raises an error if integration name is invalid' do
expect { described_class.integration_name_to_model('foo') }.to raise_exception(NameError, /uninitialized constant FooService/)
it 'raises an error if the name is unknown' do
expect { described_class.integration_name_to_type('foo') }
.to raise_exception(described_class::UnknownType, /foo/)
end
it 'handles all available_integration_names' do
types = described_class.available_integration_names.map { described_class.integration_name_to_type(_1) }
expect(types).to all(start_with('Integrations::'))
end
end
describe '.integration_name_to_type' do
it 'transforms the name to a type' do
expect(described_class.integration_name_to_type('asana')).to eq('AsanaService')
describe '.integration_name_to_model' do
it 'raises an error if integration name is invalid' do
expect { described_class.integration_name_to_model('foo') }.to raise_exception(described_class::UnknownType, /foo/)
end
end

View File

@ -7,7 +7,7 @@ RSpec.describe Integrations::Slack do
describe '#execute' do
before do
stub_request(:post, "https://slack.service.url/")
stub_request(:post, slack_integration.webhook)
end
let_it_be(:slack_integration) { create(:integrations_slack, branches_to_be_notified: 'all') }

View File

@ -1470,7 +1470,7 @@ RSpec.describe Project, factory_default: :keep do
context 'when there is an active external issue tracker integration' do
let!(:integration) do
create(:integration, project: project, type: 'JiraService', category: 'issue_tracker', active: true)
create(:jira_integration, project: project, category: 'issue_tracker')
end
specify { is_expected.to eq(true) }
@ -1489,7 +1489,7 @@ RSpec.describe Project, factory_default: :keep do
context 'when there are two active external issue tracker integrations' do
let_it_be(:second_integration) do
create(:integration, project: project, type: 'CustomIssueTracker', category: 'issue_tracker', active: true)
create(:custom_issue_tracker_integration, project: project, category: 'issue_tracker')
end
it 'does not become false when external issue tracker integration is destroyed' do

View File

@ -16,6 +16,7 @@ RSpec.describe 'query Jira service' do
services(active: true, type: JIRA_SERVICE) {
nodes {
type
serviceType
}
}
}
@ -23,7 +24,7 @@ RSpec.describe 'query Jira service' do
)
end
let(:services) { graphql_data.dig('project', 'services', 'nodes')}
let(:services) { graphql_data.dig('project', 'services', 'nodes') }
it_behaves_like 'unauthorized users cannot read services'
@ -35,10 +36,8 @@ RSpec.describe 'query Jira service' do
it_behaves_like 'a working graphql query'
it 'retuns list of jira imports' do
service = services.first
expect(service['type']).to eq('JiraService')
it 'returns list of jira integrations' do
expect(services).to contain_exactly({ 'type' => 'JiraService', 'serviceType' => 'JIRA_SERVICE' })
end
end
end

View File

@ -13,7 +13,7 @@ RSpec.describe Deployments::HooksWorker do
it 'executes project services for deployment_hooks' do
deployment = create(:deployment, :running)
project = deployment.project
service = create(:integration, type: 'SlackService', project: project, deployment_events: true, active: true)
service = create(:integrations_slack, project: project, deployment_events: true)
expect(ProjectServiceWorker).to receive(:perform_async).with(service.id, an_instance_of(Hash))
@ -23,7 +23,7 @@ RSpec.describe Deployments::HooksWorker do
it 'does not execute an inactive service' do
deployment = create(:deployment, :running)
project = deployment.project
create(:integration, type: 'SlackService', project: project, deployment_events: true, active: false)
create(:integrations_slack, project: project, deployment_events: true, active: false)
expect(ProjectServiceWorker).not_to receive(:perform_async)