summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-04-13 15:08:16 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-04-13 15:08:16 +0000
commit907fd5d94ecec19ff7de4986e83e75e6fa082558 (patch)
tree5729bfd4ce7d552a0cb5e1a8f4b2437c68faf4b5 /doc
parent0cb47d7129c3d5d7bc91d32222ca70d46cb976ca (diff)
downloadgitlab-ce-907fd5d94ecec19ff7de4986e83e75e6fa082558.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'doc')
-rw-r--r--doc/administration/geo/replication/troubleshooting.md43
-rw-r--r--doc/api/api_resources.md139
-rw-r--r--doc/api/cluster_agents.md238
-rw-r--r--doc/api/deployments.md57
-rw-r--r--doc/api/group_protected_environments.md1
-rw-r--r--doc/api/protected_environments.md23
-rw-r--r--doc/ci/environments/deployment_approvals.md55
-rw-r--r--doc/development/go_guide/go_upgrade.md29
-rw-r--r--doc/development/snowplow/implementation.md35
-rw-r--r--doc/development/snowplow/index.md17
-rw-r--r--doc/development/snowplow/schemas.md9
-rw-r--r--doc/user/clusters/agent/ci_cd_tunnel.md5
-rw-r--r--doc/user/clusters/agent/index.md2
-rw-r--r--doc/user/project/code_owners.md5
14 files changed, 543 insertions, 115 deletions
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index 8f55ce99787..03b7e0e4983 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -88,27 +88,44 @@ node running Rails (Puma, Sidekiq, or Geo Log Cursor) on the Geo **secondary** s
sudo gitlab-rake geo:status
```
-Example output:
+The output includes:
+
+- a count of "failed" items if any failures occurred
+- the percentage of "succeeded" items, relative to the "total"
+
+Example:
```plaintext
http://secondary.example.com/
-----------------------------------------------------
- GitLab Version: 11.10.4-ee
+ GitLab Version: 14.9.2-ee
Geo Role: Secondary
Health Status: Healthy
- Repositories: 289/289 (100%)
- Verified Repositories: 289/289 (100%)
- Wikis: 289/289 (100%)
- Verified Wikis: 289/289 (100%)
- LFS Objects: 8/8 (100%)
- Attachments: 5/5 (100%)
- CI job artifacts: 0/0 (0%)
- Repositories Checked: 0/289 (0%)
+ Repositories: succeeded 12345 / total 12345 (100%)
+ Verified Repositories: succeeded 12345 / total 12345 (100%)
+ Wikis: succeeded 6789 / total 6789 (100%)
+ Verified Wikis: succeeded 6789 / total 6789 (100%)
+ Attachments: succeeded 4 / total 4 (100%)
+ CI job artifacts: succeeded 0 / total 0 (0%)
+ Design repositories: succeeded 1 / total 1 (100%)
+ LFS Objects: failed 1 / succeeded 2 / total 3 (67%)
+ Merge Request Diffs: succeeded 0 / total 0 (0%)
+ Package Files: failed 1 / succeeded 2 / total 3 (67%)
+ Terraform State Versions: failed 1 / succeeded 2 / total 3 (67%)
+ Snippet Repositories: failed 1 / succeeded 2 / total 3 (67%)
+ Group Wiki Repositories: succeeded 4 / total 4 (100%)
+ Pipeline Artifacts: failed 3 / succeeded 0 / total 3 (0%)
+ Pages Deployments: succeeded 0 / total 0 (0%)
+ Repositories Checked: failed 5 / succeeded 0 / total 5 (0%)
+ Package Files Verified: succeeded 0 / total 10 (0%)
+ Terraform State Versions Verified: succeeded 0 / total 10 (0%)
+ Snippet Repositories Verified: succeeded 99 / total 100 (99%)
+ Pipeline Artifacts Verified: succeeded 0 / total 10 (0%)
Sync Settings: Full
Database replication lag: 0 seconds
- Last event ID seen from primary: 10215 (about 2 minutes ago)
- Last event ID processed by cursor: 10215 (about 2 minutes ago)
- Last status report was: 2 minutes ago
+ Last event ID seen from primary: 12345 (about 2 minutes ago)
+ Last event ID processed by cursor: 12345 (about 2 minutes ago)
+ Last status report was: 1 minute ago
```
### Check if PostgreSQL replication is working
diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index 1981cd83f97..f6d1e554aae 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -21,76 +21,77 @@ See also:
The following API resources are available in the project context:
-| Resource | Available endpoints |
-|:------------------------------------------------------------------------|:--------------------|
-| [Access requests](access_requests.md) | `/projects/:id/access_requests` (also available for groups) |
-| [Access tokens](resource_access_tokens.md) | `/projects/:id/access_tokens` (also available for groups) |
-| [Award emoji](award_emoji.md) | `/projects/:id/issues/.../award_emoji`, `/projects/:id/merge_requests/.../award_emoji`, `/projects/:id/snippets/.../award_emoji` |
-| [Branches](branches.md) | `/projects/:id/repository/branches/`, `/projects/:id/repository/merged_branches` |
-| [Commits](commits.md) | `/projects/:id/repository/commits`, `/projects/:id/statuses` |
-| [Container Registry](container_registry.md) | `/projects/:id/registry/repositories` |
-| [Custom attributes](custom_attributes.md) | `/projects/:id/custom_attributes` (also available for groups and users) |
-| [Debian distributions](packages/debian_project_distributions.md) | `/projects/:id/debian_distributions` (also available for groups) |
-| [Dependencies](dependencies.md) **(ULTIMATE)** | `/projects/:id/dependencies` |
-| [Deploy keys](deploy_keys.md) | `/projects/:id/deploy_keys` (also available standalone) |
-| [Deploy tokens](deploy_tokens.md) | `/projects/:id/deploy_tokens` (also available for groups and standalone) |
-| [Deployments](deployments.md) | `/projects/:id/deployments` |
+| Resource | Available endpoints |
+|:------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| [Access requests](access_requests.md) | `/projects/:id/access_requests` (also available for groups) |
+| [Access tokens](resource_access_tokens.md) | `/projects/:id/access_tokens` (also available for groups) |
+| [Agents](cluster_agents.md) | `/projects/:id/cluster_agents` |
+| [Award emoji](award_emoji.md) | `/projects/:id/issues/.../award_emoji`, `/projects/:id/merge_requests/.../award_emoji`, `/projects/:id/snippets/.../award_emoji` |
+| [Branches](branches.md) | `/projects/:id/repository/branches/`, `/projects/:id/repository/merged_branches` |
+| [Commits](commits.md) | `/projects/:id/repository/commits`, `/projects/:id/statuses` |
+| [Container Registry](container_registry.md) | `/projects/:id/registry/repositories` |
+| [Custom attributes](custom_attributes.md) | `/projects/:id/custom_attributes` (also available for groups and users) |
+| [Debian distributions](packages/debian_project_distributions.md) | `/projects/:id/debian_distributions` (also available for groups) |
+| [Dependencies](dependencies.md) **(ULTIMATE)** | `/projects/:id/dependencies` |
+| [Deploy keys](deploy_keys.md) | `/projects/:id/deploy_keys` (also available standalone) |
+| [Deploy tokens](deploy_tokens.md) | `/projects/:id/deploy_tokens` (also available for groups and standalone) |
+| [Deployments](deployments.md) | `/projects/:id/deployments` |
| [Discussions](discussions.md) (threaded comments) | `/projects/:id/issues/.../discussions`, `/projects/:id/snippets/.../discussions`, `/projects/:id/merge_requests/.../discussions`, `/projects/:id/commits/.../discussions` (also available for groups) |
-| [Environments](environments.md) | `/projects/:id/environments` |
-| [Error Tracking](error_tracking.md) | `/projects/:id/error_tracking/settings` |
-| [Events](events.md) | `/projects/:id/events` (also available for users and standalone) |
-| [Feature Flag User Lists](feature_flag_user_lists.md) | `/projects/:id/feature_flags_user_lists` |
-| [Feature Flags](feature_flags.md) | `/projects/:id/feature_flags` |
-| [Freeze Periods](freeze_periods.md) | `/projects/:id/freeze_periods` |
-| [Integrations](integrations.md) (Formerly "services") | `/projects/:id/integrations` |
-| [Invitations](invitations.md) | `/projects/:id/invitations` (also available for groups) |
-| [Issue boards](boards.md) | `/projects/:id/boards` |
-| [Issue links](issue_links.md) | `/projects/:id/issues/.../links` |
-| [Issues Statistics](issues_statistics.md) | `/projects/:id/issues_statistics` (also available for groups and standalone) |
-| [Issues](issues.md) | `/projects/:id/issues` (also available for groups and standalone) |
-| [Iterations](iterations.md) **(PREMIUM)** | `/projects/:id/iterations` (also available for groups) |
-| [Jobs](jobs.md) | `/projects/:id/jobs`, `/projects/:id/pipelines/.../jobs` |
-| [Labels](labels.md) | `/projects/:id/labels` |
-| [Managed licenses](managed_licenses.md) **(ULTIMATE)** | `/projects/:id/managed_licenses` |
-| [Members](members.md) | `/projects/:id/members` (also available for groups) |
-| [Merge request approvals](merge_request_approvals.md) **(PREMIUM)** | `/projects/:id/approvals`, `/projects/:id/merge_requests/.../approvals` |
-| [Merge requests](merge_requests.md) | `/projects/:id/merge_requests` (also available for groups and standalone) |
-| [Merge trains](merge_trains.md) | `/projects/:id/merge_trains` |
-| [Notes](notes.md) (comments) | `/projects/:id/issues/.../notes`, `/projects/:id/snippets/.../notes`, `/projects/:id/merge_requests/.../notes` (also available for groups) |
-| [Notification settings](notification_settings.md) | `/projects/:id/notification_settings` (also available for groups and standalone) |
-| [Packages](packages.md) | `/projects/:id/packages` |
-| [Pages domains](pages_domains.md) | `/projects/:id/pages` (also available standalone) |
-| [Pipeline schedules](pipeline_schedules.md) | `/projects/:id/pipeline_schedules` |
-| [Pipeline triggers](pipeline_triggers.md) | `/projects/:id/triggers` |
-| [Pipelines](pipelines.md) | `/projects/:id/pipelines` |
-| [Project badges](project_badges.md) | `/projects/:id/badges` |
-| [Project clusters](project_clusters.md) | `/projects/:id/clusters` |
-| [Project import/export](project_import_export.md) | `/projects/:id/export`, `/projects/import`, `/projects/:id/import` |
-| [Project milestones](milestones.md) | `/projects/:id/milestones` |
-| [Project snippets](project_snippets.md) | `/projects/:id/snippets` |
-| [Project templates](project_templates.md) | `/projects/:id/templates` |
-| [Project vulnerabilities](project_vulnerabilities.md) **(ULTIMATE)** | `/projects/:id/templates` |
-| [Project wikis](wikis.md) | `/projects/:id/wikis` |
-| [Project-level variables](project_level_variables.md) | `/projects/:id/variables` |
-| [Projects](projects.md) including setting Webhooks | `/projects`, `/projects/:id/hooks` (also available for users) |
-| [Protected branches](protected_branches.md) | `/projects/:id/protected_branches` |
-| [Protected environments](protected_environments.md) | `/projects/:id/protected_environments` |
-| [Protected tags](protected_tags.md) | `/projects/:id/protected_tags` |
-| [Release links](releases/links.md) | `/projects/:id/releases/.../assets/links` |
-| [Releases](releases/index.md) | `/projects/:id/releases` |
-| [Remote mirrors](remote_mirrors.md) | `/projects/:id/remote_mirrors` |
-| [Repositories](repositories.md) | `/projects/:id/repository` |
-| [Repository files](repository_files.md) | `/projects/:id/repository/files` |
-| [Repository submodules](repository_submodules.md) | `/projects/:id/repository/submodules` |
-| [Resource label events](resource_label_events.md) | `/projects/:id/issues/.../resource_label_events`, `/projects/:id/merge_requests/.../resource_label_events` (also available for groups) |
-| [Runners](runners.md) | `/projects/:id/runners` (also available standalone) |
-| [Search](search.md) | `/projects/:id/search` (also available for groups and standalone) |
-| [Tags](tags.md) | `/projects/:id/repository/tags` |
-| [User-starred metrics dashboards](metrics_user_starred_dashboards.md ) | `/projects/:id/metrics/user_starred_dashboards` |
-| [Visual Review discussions](visual_review_discussions.md) **(PREMIUM)** | `/projects/:id/merge_requests/:merge_request_id/visual_review_discussions` |
-| [Vulnerabilities](vulnerabilities.md) **(ULTIMATE)** | `/vulnerabilities/:id` |
-| [Vulnerability exports](vulnerability_exports.md) **(ULTIMATE)** | `/projects/:id/vulnerability_exports` |
-| [Vulnerability findings](vulnerability_findings.md) **(ULTIMATE)** | `/projects/:id/vulnerability_findings` |
+| [Environments](environments.md) | `/projects/:id/environments` |
+| [Error Tracking](error_tracking.md) | `/projects/:id/error_tracking/settings` |
+| [Events](events.md) | `/projects/:id/events` (also available for users and standalone) |
+| [Feature Flag User Lists](feature_flag_user_lists.md) | `/projects/:id/feature_flags_user_lists` |
+| [Feature Flags](feature_flags.md) | `/projects/:id/feature_flags` |
+| [Freeze Periods](freeze_periods.md) | `/projects/:id/freeze_periods` |
+| [Integrations](integrations.md) (Formerly "services") | `/projects/:id/integrations` |
+| [Invitations](invitations.md) | `/projects/:id/invitations` (also available for groups) |
+| [Issue boards](boards.md) | `/projects/:id/boards` |
+| [Issue links](issue_links.md) | `/projects/:id/issues/.../links` |
+| [Issues Statistics](issues_statistics.md) | `/projects/:id/issues_statistics` (also available for groups and standalone) |
+| [Issues](issues.md) | `/projects/:id/issues` (also available for groups and standalone) |
+| [Iterations](iterations.md) **(PREMIUM)** | `/projects/:id/iterations` (also available for groups) |
+| [Jobs](jobs.md) | `/projects/:id/jobs`, `/projects/:id/pipelines/.../jobs` |
+| [Labels](labels.md) | `/projects/:id/labels` |
+| [Managed licenses](managed_licenses.md) **(ULTIMATE)** | `/projects/:id/managed_licenses` |
+| [Members](members.md) | `/projects/:id/members` (also available for groups) |
+| [Merge request approvals](merge_request_approvals.md) **(PREMIUM)** | `/projects/:id/approvals`, `/projects/:id/merge_requests/.../approvals` |
+| [Merge requests](merge_requests.md) | `/projects/:id/merge_requests` (also available for groups and standalone) |
+| [Merge trains](merge_trains.md) | `/projects/:id/merge_trains` |
+| [Notes](notes.md) (comments) | `/projects/:id/issues/.../notes`, `/projects/:id/snippets/.../notes`, `/projects/:id/merge_requests/.../notes` (also available for groups) |
+| [Notification settings](notification_settings.md) | `/projects/:id/notification_settings` (also available for groups and standalone) |
+| [Packages](packages.md) | `/projects/:id/packages` |
+| [Pages domains](pages_domains.md) | `/projects/:id/pages` (also available standalone) |
+| [Pipeline schedules](pipeline_schedules.md) | `/projects/:id/pipeline_schedules` |
+| [Pipeline triggers](pipeline_triggers.md) | `/projects/:id/triggers` |
+| [Pipelines](pipelines.md) | `/projects/:id/pipelines` |
+| [Project badges](project_badges.md) | `/projects/:id/badges` |
+| [Project clusters](project_clusters.md) | `/projects/:id/clusters` |
+| [Project import/export](project_import_export.md) | `/projects/:id/export`, `/projects/import`, `/projects/:id/import` |
+| [Project milestones](milestones.md) | `/projects/:id/milestones` |
+| [Project snippets](project_snippets.md) | `/projects/:id/snippets` |
+| [Project templates](project_templates.md) | `/projects/:id/templates` |
+| [Project vulnerabilities](project_vulnerabilities.md) **(ULTIMATE)** | `/projects/:id/templates` |
+| [Project wikis](wikis.md) | `/projects/:id/wikis` |
+| [Project-level variables](project_level_variables.md) | `/projects/:id/variables` |
+| [Projects](projects.md) including setting Webhooks | `/projects`, `/projects/:id/hooks` (also available for users) |
+| [Protected branches](protected_branches.md) | `/projects/:id/protected_branches` |
+| [Protected environments](protected_environments.md) | `/projects/:id/protected_environments` |
+| [Protected tags](protected_tags.md) | `/projects/:id/protected_tags` |
+| [Release links](releases/links.md) | `/projects/:id/releases/.../assets/links` |
+| [Releases](releases/index.md) | `/projects/:id/releases` |
+| [Remote mirrors](remote_mirrors.md) | `/projects/:id/remote_mirrors` |
+| [Repositories](repositories.md) | `/projects/:id/repository` |
+| [Repository files](repository_files.md) | `/projects/:id/repository/files` |
+| [Repository submodules](repository_submodules.md) | `/projects/:id/repository/submodules` |
+| [Resource label events](resource_label_events.md) | `/projects/:id/issues/.../resource_label_events`, `/projects/:id/merge_requests/.../resource_label_events` (also available for groups) |
+| [Runners](runners.md) | `/projects/:id/runners` (also available standalone) |
+| [Search](search.md) | `/projects/:id/search` (also available for groups and standalone) |
+| [Tags](tags.md) | `/projects/:id/repository/tags` |
+| [User-starred metrics dashboards](metrics_user_starred_dashboards.md ) | `/projects/:id/metrics/user_starred_dashboards` |
+| [Visual Review discussions](visual_review_discussions.md) **(PREMIUM)** | `/projects/:id/merge_requests/:merge_request_id/visual_review_discussions` |
+| [Vulnerabilities](vulnerabilities.md) **(ULTIMATE)** | `/vulnerabilities/:id` |
+| [Vulnerability exports](vulnerability_exports.md) **(ULTIMATE)** | `/projects/:id/vulnerability_exports` |
+| [Vulnerability findings](vulnerability_findings.md) **(ULTIMATE)** | `/projects/:id/vulnerability_findings` |
## Group resources
diff --git a/doc/api/cluster_agents.md b/doc/api/cluster_agents.md
new file mode 100644
index 00000000000..37cc4a24342
--- /dev/null
+++ b/doc/api/cluster_agents.md
@@ -0,0 +1,238 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Agents API **(FREE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83270) in GitLab 14.10.
+
+Use the Agents API to work with the GitLab agent for Kubernetes.
+
+## List the agents for a project
+
+Returns the list of agents registered for the project.
+
+You must have at least the Developer role to use this endpoint.
+
+```plaintext
+GET /projects/:id/cluster_agents
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|-----------|-------------------|-----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer or string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) maintained by the authenticated user |
+
+Response:
+
+The response is a list of agents with the following fields:
+
+| Attribute | Type | Description |
+|--------------------------------------|----------|------------------------------------------------------|
+| `id` | integer | ID of the agent |
+| `name` | string | Name of the agent |
+| `config_project` | object | Object representing the project the agent belongs to |
+| `config_project.id` | integer | ID of the project |
+| `config_project.description` | string | Description of the project |
+| `config_project.name` | string | Name of the project |
+| `config_project.name_with_namespace` | string | Full name with namespace of the project |
+| `config_project.path` | string | Path to the project |
+| `config_project.path_with_namespace` | string | Full path with namespace to the project |
+| `config_project.created_at` | string | ISO8601 datetime when the project was created |
+| `created_at` | string | ISO8601 datetime when the agent was created |
+| `created_by_user_id` | integer | ID of the user who created the agent |
+
+Example request:
+
+```shell
+curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects/20/cluster_agents"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 1,
+ "name": "agent-1",
+ "config_project": {
+ "id": 20,
+ "description": "",
+ "name": "test",
+ "name_with_namespace": "Administrator / test",
+ "path": "test",
+ "path_with_namespace": "root/test",
+ "created_at": "2022-03-20T20:42:40.221Z"
+ },
+ "created_at": "2022-04-20T20:42:40.221Z",
+ "created_by_user_id": 42
+ },
+ {
+ "id": 2,
+ "name": "agent-2",
+ "config_project": {
+ "id": 20,
+ "description": "",
+ "name": "test",
+ "name_with_namespace": "Administrator / test",
+ "path": "test",
+ "path_with_namespace": "root/test",
+ "created_at": "2022-03-20T20:42:40.221Z"
+ },
+ "created_at": "2022-04-20T20:42:40.221Z",
+ "created_by_user_id": 42
+ }
+]
+```
+
+## Get details about an agent
+
+Gets a single agent details.
+
+You must have at least the Developer role to use this endpoint.
+
+```shell
+GET /projects/:id/cluster_agents/:agent_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|------------|-------------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer or string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) maintained by the authenticated user |
+| `agent_id` | integer | yes | ID of the agent |
+
+Response:
+
+The response is a single agent with the following fields:
+
+| Attribute | Type | Description |
+|--------------------------------------|---------|------------------------------------------------------|
+| `id` | integer | ID of the agent |
+| `name` | string | Name of the agent |
+| `config_project` | object | Object representing the project the agent belongs to |
+| `config_project.id` | integer | ID of the project |
+| `config_project.description` | string | Description of the project |
+| `config_project.name` | string | Name of the project |
+| `config_project.name_with_namespace` | string | Full name with namespace of the project |
+| `config_project.path` | string | Path to the project |
+| `config_project.path_with_namespace` | string | Full path with namespace to the project |
+| `config_project.created_at` | string | ISO8601 datetime when the project was created |
+| `created_at` | string | ISO8601 datetime when the agent was created |
+| `created_by_user_id` | integer | ID of the user who created the agent |
+
+Example request:
+
+```shell
+curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects/20/cluster_agents/1"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "agent-1",
+ "config_project": {
+ "id": 20,
+ "description": "",
+ "name": "test",
+ "name_with_namespace": "Administrator / test",
+ "path": "test",
+ "path_with_namespace": "root/test",
+ "created_at": "2022-03-20T20:42:40.221Z"
+ },
+ "created_at": "2022-04-20T20:42:40.221Z",
+ "created_by_user_id": 42
+}
+```
+
+## Register an agent with a project
+
+Registers an agent to the project.
+
+You must have at least the Maintainer role to use this endpoint.
+
+```shell
+POST /projects/:id/cluster_agents
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|-----------|-------------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer or string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) maintained by the authenticated user |
+| `name` | string | yes | Name for the agent |
+
+Response:
+
+The response is the new agent with the following fields:
+
+| Attribute | Type | Description |
+|--------------------------------------|---------|------------------------------------------------------|
+| `id` | integer | ID of the agent |
+| `name` | string | Name of the agent |
+| `config_project` | object | Object representing the project the agent belongs to |
+| `config_project.id` | integer | ID of the project |
+| `config_project.description` | string | Description of the project |
+| `config_project.name` | string | Name of the project |
+| `config_project.name_with_namespace` | string | Full name with namespace of the project |
+| `config_project.path` | string | Path to the project |
+| `config_project.path_with_namespace` | string | Full path with namespace to the project |
+| `config_project.created_at` | string | ISO8601 datetime when the project was created |
+| `created_at` | string | ISO8601 datetime when the agent was created |
+| `created_by_user_id` | integer | ID of the user who created the agent |
+
+Example request:
+
+```shell
+curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects/20/cluster_agents" \
+ -H "Content-Type:application/json" \
+ -X POST --data '{"name":"some-agent"}'
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "agent-1",
+ "config_project": {
+ "id": 20,
+ "description": "",
+ "name": "test",
+ "name_with_namespace": "Administrator / test",
+ "path": "test",
+ "path_with_namespace": "root/test",
+ "created_at": "2022-03-20T20:42:40.221Z"
+ },
+ "created_at": "2022-04-20T20:42:40.221Z",
+ "created_by_user_id": 42
+}
+```
+
+## Delete a registered agent
+
+Deletes an existing agent registration.
+
+You must have at least the Maintainer role to use this endpoint.
+
+```plaintext
+DELETE /projects/:id/cluster_agents/:agent_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|------------|-------------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer or string | yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) maintained by the authenticated user |
+| `agent_id` | integer | yes | ID of the agent |
+
+Example request:
+
+```shell
+curl --request DELETE --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects/20/cluster_agents/1
+```
diff --git a/doc/api/deployments.md b/doc/api/deployments.md
index c2e2b7f87ba..fb255bfa226 100644
--- a/doc/api/deployments.md
+++ b/doc/api/deployments.md
@@ -265,7 +265,7 @@ Example response:
}
```
-Deployments created by users on GitLab Premium or higher include the `approvals` and `pending_approval_count` properties:
+When the [unified approval setting](../ci/environments/deployment_approvals.md#unified-approval-setting) is configured, deployments created by users on GitLab Premium or higher include the `approvals` and `pending_approval_count` properties:
```json
{
@@ -290,6 +290,48 @@ Deployments created by users on GitLab Premium or higher include the `approvals`
}
```
+When the [multiple approval rules](../ci/environments/deployment_approvals.md#multiple-approval-rules) is configured, deployments created by users on GitLab Premium or higher include the `approval_summary` property:
+
+```json
+{
+ "approval_summary": {
+ "rules": [
+ {
+ "user_id": null,
+ "group_id": 134,
+ "access_level": null,
+ "access_level_description": "qa-group",
+ "required_approvals": 1,
+ "deployment_approvals": []
+ },
+ {
+ "user_id": null,
+ "group_id": 135,
+ "access_level": null,
+ "access_level_description": "security-group",
+ "required_approvals": 2,
+ "deployment_approvals": [
+ {
+ "user": {
+ "id": 100,
+ "username": "security-user-1",
+ "name": "security user-1",
+ "state": "active",
+ "avatar_url": "https://www.gravatar.com/avatar/e130fcd3a1681f41a3de69d10841afa9?s=80&d=identicon",
+ "web_url": "http://localhost:3000/security-user-1"
+ },
+ "status": "approved",
+ "created_at": "2022-04-11T03:37:03.058Z",
+ "comment": null
+ }
+ ]
+ }
+ ]
+ }
+ ...
+}
+```
+
## Create a deployment
```plaintext
@@ -455,9 +497,10 @@ POST /projects/:id/deployments/:deployment_id/approval
| `deployment_id` | integer | yes | The ID of the deployment. |
| `status` | string | yes | The status of the approval (either `approved` or `rejected`). |
| `comment` | string | no | A comment to go with the approval |
+| `represented_as`| string | no | The name of the User/Group/Role to use for the approval, when the user belongs to [multiple approval rules](../ci/environments/deployment_approvals.md#multiple-approval-rules). |
```shell
-curl --data "status=approved&comment=Looks good to me" \
+curl --data "status=approved&comment=Looks good to me&represented_as=security" \
--header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/1/approval"
```
@@ -466,12 +509,12 @@ Example response:
```json
{
"user": {
- "name": "Administrator",
- "username": "root",
- "id": 1,
+ "id": 100,
+ "username": "security-user-1",
+ "name": "security user-1",
"state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://localhost:3000/root"
+ "avatar_url": "https://www.gravatar.com/avatar/e130fcd3a1681f41a3de69d10841afa9?s=80&d=identicon",
+ "web_url": "http://localhost:3000/security-user-1"
},
"status": "approved",
"created_at": "2022-02-24T20:22:30.097Z",
diff --git a/doc/api/group_protected_environments.md b/doc/api/group_protected_environments.md
index 6ce4e1791b0..f8f9b853354 100644
--- a/doc/api/group_protected_environments.md
+++ b/doc/api/group_protected_environments.md
@@ -107,6 +107,7 @@ POST /groups/:id/protected_environments
| `name` | string | yes | The deployment tier of the protected environment. One of `production`, `staging`, `testing`, `development`, or `other`. Read more about [deployment tiers](../ci/environments/index.md#deployment-tier-of-environments).|
| `deploy_access_levels` | array | yes | Array of access levels allowed to deploy, with each described by a hash. One of `user_id`, `group_id` or `access_level`. They take the form of `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}` respectively. |
| `required_approval_count` | integer | no | The number of approvals required to deploy to this environment. This is part of Deployment Approvals, which isn't yet available for use. For details, see [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/343864). |
+| `approval_rules` | array | no | Array of access levels allowed to approve, with each described by a hash. One of `user_id`, `group_id` or `access_level`. They take the form of `{user_id: integer}`, `{group_id: integer}` or `{access_level: integer}` respectively. You can also specify the number of required approvals from the specified entity with `required_approvals` field. See [Multiple approval rules](../ci/environments/deployment_approvals.md#multiple-approval-rules) for more information. |
The assignable `user_id` are the users who belong to the given group with the Maintainer role (or above).
The assignable `group_id` are the sub-groups under the given group.
diff --git a/doc/api/protected_environments.md b/doc/api/protected_environments.md
index 61587136a14..fc7eb5caf6d 100644
--- a/doc/api/protected_environments.md
+++ b/doc/api/protected_environments.md
@@ -99,7 +99,7 @@ POST /projects/:id/protected_environments
```shell
curl --header 'Content-Type: application/json' --request POST \
- --data '{"name": "production", "deploy_access_levels": [{"group_id": 9899826}]}' \
+ --data '{"name": "production", "deploy_access_levels": [{"group_id": 9899826}], "approval_rules": [{"group_id": 134}, {"group_id": 135, "required_approvals": 2}]}' \
--header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/projects/22034114/protected_environments"
```
@@ -110,8 +110,9 @@ curl --header 'Content-Type: application/json' --request POST \
| `name` | string | yes | The name of the environment. |
| `deploy_access_levels` | array | yes | Array of access levels allowed to deploy, with each described by a hash. |
| `required_approval_count` | integer | no | The number of approvals required to deploy to this environment. This is part of Deployment Approvals, which isn't yet available for use. For details, see [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/343864). |
+| `approval_rules` | array | no | Array of access levels allowed to approve, with each described by a hash. See [Multiple approval rules](../ci/environments/deployment_approvals.md#multiple-approval-rules) for more information. |
-Elements in the `deploy_access_levels` array should be one of `user_id`, `group_id` or
+Elements in the `deploy_access_levels` and `approval_rules` array should be one of `user_id`, `group_id` or
`access_level`, and take the form `{user_id: integer}`, `{group_id: integer}` or
`{access_level: integer}`.
Each user must have access to the project and each group must [have this project shared](../user/project/members/share_project_with_groups.md).
@@ -129,7 +130,23 @@ Example response:
"group_id": 9899826
}
],
- "required_approval_count": 0
+ "required_approval_count": 0,
+ "approval_rules": [
+ {
+ "user_id": null,
+ "group_id": 134,
+ "access_level": null,
+ "access_level_description": "qa-group",
+ "required_approvals": 1
+ },
+ {
+ "user_id": null,
+ "group_id": 135,
+ "access_level": null,
+ "access_level_description": "security-group",
+ "required_approvals": 2
+ }
+ ]
}
```
diff --git a/doc/ci/environments/deployment_approvals.md b/doc/ci/environments/deployment_approvals.md
index 0f7bd2c14a3..e3735f2718e 100644
--- a/doc/ci/environments/deployment_approvals.md
+++ b/doc/ci/environments/deployment_approvals.md
@@ -52,6 +52,19 @@ Example:
### Require approvals for a protected environment
+There are two ways to configure the approval requirements:
+
+- [Unified approval setting](#unified-approval-setting) ... You can define who can execute **and** approve deployments.
+ This is useful when there is no separation of duties between executors and approvers in your oraganization.
+- [Multiple approval rules](#multiple-approval-rules) ... You can define who can execute **or** approve deployments.
+ This is useful when there is a separation of duties between executors and approvers in your oraganization.
+
+NOTE:
+Multiple approval rules is a more flexible option than the unified approval setting, thus both configurations shouldn't
+co-exist and multiple approval rules takes the precedence over the unified approval setting if it happens.
+
+#### Unified approval setting
+
NOTE:
At this time, it is not possible to require approvals for an existing protected environment. The workaround is to unprotect the environment and configure approvals when re-protecting the environment.
@@ -77,6 +90,35 @@ NOTE:
To protect, update, or unprotect an environment, you must have at least the
Maintainer role.
+#### Multiple approval rules
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345678) in GitLab 14.10 with a flag named `deployment_approval_rules`. Disabled by default.
+
+1. Using the [REST API](../../api/group_protected_environments.md#protect-an-environment).
+ 1. `deploy_access_levels` represents which entity can execute the deployment job.
+ 1. `approval_rules` represents which entity can approve the deployment job.
+
+After this is configured, all jobs deploying to this environment automatically go into a blocked state and wait for approvals before running. Ensure that the number of required approvals is less than the number of users allowed to deploy.
+
+Example:
+
+```shell
+curl --header 'Content-Type: application/json' --request POST \
+ --data '{"name": "production", "deploy_access_levels": [{"group_id": 138}], "approval_rules": [{"group_id": 134}, {"group_id": 135, "required_approvals": 2}]}' \
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/groups/128/protected_environments"
+```
+
+With this setup:
+
+- The operator group (`group_id: 138`) has permission to execute the deployment jobs to the `production` environment in the organization (`group_id: 128`).
+- The QA tester group (`group_id: 134`) and security group (`group_id: 135`) have permission to approve the deployment jobs to the `production` environment in the organization (`group_id: 128`).
+- Unless two approvals from security group and one approval from QA tester group have been collected, the operator group can't execute the deployment jobs.
+
+NOTE:
+To protect, update, or unprotect an environment, you must have at least the
+Maintainer role.
+
## Approve or reject a deployment
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/342180/) in GitLab 14.9
@@ -99,6 +141,10 @@ To approve or reject a deployment to a protected environment using the UI:
1. In the deployment's row, select **Approval options** (**{thumb-up}**).
1. Select **Approve** or **Reject**.
+NOTE:
+This feature might not work as expected when [Multiple approval rules](#multiple-approval-rules) is configured.
+See the [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/355708) for planned improvement.
+
### Approve or reject a deployment using the API
Prerequisites:
@@ -127,11 +173,14 @@ curl --data "status=approved&comment=Looks good to me" \
### Using the API
-Use the [Deployments API](../../api/deployments.md) to see deployments.
+Use the [Deployments API](../../api/deployments.md#get-a-specific-deployment) to see deployments.
- The `status` field indicates if a deployment is blocked.
-- The `pending_approval_count` field indicates how many approvals are remaining to run a deployment.
-- The `approvals` field contains the deployment's approvals.
+- When the [unified approval setting](#unified-approval-setting) is configured:
+ - The `pending_approval_count` field indicates how many approvals are remaining to run a deployment.
+ - The `approvals` field contains the deployment's approvals.
+- When the [multiple approval rules](#multiple-approval-rules) is configured:
+ - The `approval_summary` field contains the current approval status per rule.
## Related features
diff --git a/doc/development/go_guide/go_upgrade.md b/doc/development/go_guide/go_upgrade.md
index a99253b9723..3267d1262f0 100644
--- a/doc/development/go_guide/go_upgrade.md
+++ b/doc/development/go_guide/go_upgrade.md
@@ -76,9 +76,27 @@ if you need help finding the correct person or labels:
1. Create the epic in `gitlab-org` group:
- Title the epic `Update Go version to <VERSION_NUMBER>`.
- Ping the engineering managers responsible for [the projects listed below](#known-dependencies-using-go).
+ - Most engineering managers can be identified on
+ [the product page](https://about.gitlab.com/handbook/product/categories/) or the
+ [feature page](https://about.gitlab.com/handbook/product/categories/features/).
+ - If you still can't find the engineering manager, use
+ [Git blame](/ee/user/project/repository/git_blame.md) to identify a maintainer
+ involved in the project.
+
+1. Create an upgrade issue for each dependency in the
+ [location indicated below](#known-dependencies-using-go) titled
+ `Support building with Go <VERSION_NUMBER>`. Add the proper labels to each issue
+ for easier triage. These should include the stage, group and section.
+ - The issue should be assigned by a member of the maintaining group.
+ - The milestone should be assigned by a member of the maintaining group.
-1. Create an upgrade issue for each dependency in the [location indicated below](#known-dependencies-using-go)
- titled `Support building with Go <VERSION_NUMBER>`. Add the proper label to each issue for easier triage.
+ NOTE:
+ Some overlap exists between project dependencies. When creating an issue for a
+ dependency that is part of a larger product, note the relationship in the issue
+ body. For example: Projects built in the context of Omnibus GitLab have their
+ runtime Go version managed by Omnibus, but "support" and compatibility should
+ be a concern of the individual project. Issues in the parent project's dependencies
+ issue should be about adding support for the updated Go version.
NOTE:
The upgrade issues must include [upgrade validation items](#upgrade-validation)
@@ -94,9 +112,10 @@ if you need help finding the correct person or labels:
- [Composition Analysis tracker](https://gitlab.com/gitlab-org/gitlab/-/issues).
- [Container Security tracker](https://gitlab.com/gitlab-org/gitlab/-/issues).
- NOTE:
- Updates to these Security analyzers should not block upgrades to Charts or Omnibus since
- the analyzers are built independently as separate container images.
+ NOTE:
+ Updates to these Security analyzers should not block upgrades to Charts or Omnibus since
+ the analyzers are built independently as separate container images.
+
1. Schedule builder updates with Distribution projects:
- Dependency and GitLab Development Kit issues created in previous steps should be set as blockers.
- Each issue should have the title `Support building with Go <VERSION_NUMBER>` and description as noted:
diff --git a/doc/development/snowplow/implementation.md b/doc/development/snowplow/implementation.md
index 6061a1d4cd2..162b77772f9 100644
--- a/doc/development/snowplow/implementation.md
+++ b/doc/development/snowplow/implementation.md
@@ -21,8 +21,25 @@ For the recommended frontend tracking implementation, see [Usage recommendations
Structured events and page views include the [`gitlab_standard`](schemas.md#gitlab_standard)
context, using the `window.gl.snowplowStandardContext` object which includes
[default data](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/views/layouts/_snowplow.html.haml)
-as base. This object can be modified for any subsequent structured event fired,
-although it's not recommended.
+as base:
+
+| Property | Example |
+| -------- | ------- |
+| `context_generated_at` | `"2022-01-01T01:00:00.000Z"` |
+| `environment` | `"production"` |
+| `extra` | `{}` |
+| `namespace_id` | `123` |
+| `plan` | `"gold"` |
+| `project_id` | `456` |
+| `source` | `"gitlab-rails"` |
+| `user_id` | `789`* |
+
+_\* Undergoes a pseudonymization process at the collector level._
+
+These properties [are overriden](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/tracking/get_standard_context.js)
+with frontend-specific values, like `source` (`gitlab-javascript`), `google_analytics_id`
+and the custom `extra` object. You can modify this object for any subsequent
+structured event that fires, although this is not recommended.
Tracking implementations must have an `action` and a `category`. You can provide additional
properties from the [structured event taxonomy](index.md#structured-event-taxonomy), in
@@ -396,13 +413,13 @@ Use the following arguments:
|------------|---------------------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------|
| `category` | String | | Area or aspect of the application. For example, `HealthCheckController` or `Lfs::FileTransformer`. |
| `action` | String | | The action being taken. For example, a controller action such as `create`, or an Active Record callback. |
-| `label` | String | nil | The specific element or object to act on. This can be one of the following: the label of the element, for example, a tab labeled 'Create from template' for `create_from_template`; a unique identifier if no text is available, for example, `groups_dropdown_close` for closing the Groups dropdown in the top bar; or the name or title attribute of a record being created. |
-| `property` | String | nil | Any additional property of the element, or object being acted on. |
-| `value` | Numeric | nil | Describes a numeric value (decimal) directly related to the event. This could be the value of an input. For example, `10` when clicking `internal` visibility. |
-| `context` | Array\[SelfDescribingJSON\] | nil | An array of custom contexts to send with this event. Most events should not have any custom contexts. |
-| `project` | Project | nil | The project associated with the event. |
-| `user` | User | nil | The user associated with the event. |
-| `namespace` | Namespace | nil | The namespace associated with the event. |
+| `label` | String | `nil` | The specific element or object to act on. This can be one of the following: the label of the element, for example, a tab labeled 'Create from template' for `create_from_template`; a unique identifier if no text is available, for example, `groups_dropdown_close` for closing the Groups dropdown in the top bar; or the name or title attribute of a record being created. |
+| `property` | String | `nil` | Any additional property of the element, or object being acted on. |
+| `value` | Numeric | `nil` | Describes a numeric value (decimal) directly related to the event. This could be the value of an input. For example, `10` when clicking `internal` visibility. |
+| `context` | Array\[SelfDescribingJSON\] | `nil` | An array of custom contexts to send with this event. Most events should not have any custom contexts. |
+| `project` | Project | `nil` | The project associated with the event. |
+| `user` | User | `nil` | The user associated with the event. This value undergoes a pseudonymization process at the collector level. |
+| `namespace` | Namespace | `nil` | The namespace associated with the event. |
| `extra` | Hash | `{}` | Additional keyword arguments are collected into a hash and sent with the event. |
### Unit testing
diff --git a/doc/development/snowplow/index.md b/doc/development/snowplow/index.md
index 29f4514a21e..9b684757fe1 100644
--- a/doc/development/snowplow/index.md
+++ b/doc/development/snowplow/index.md
@@ -150,6 +150,23 @@ ORDER BY page_view_start DESC
LIMIT 100
```
+#### Top 20 users who fired `reply_comment_button` in the last 30 days
+
+```sql
+SELECT
+ count(*) as hits,
+ se_action,
+ se_category,
+ gsc_pseudonymized_user_id
+FROM legacy.snowplow_gitlab_events_30
+WHERE
+ se_label = 'reply_comment_button'
+ AND gsc_pseudonymized_user_id IS NOT NULL
+GROUP BY gsc_pseudonymized_user_id, se_category, se_action
+ORDER BY count(*) DESC
+LIMIT 20
+```
+
#### Query JSON formatted data
```sql
diff --git a/doc/development/snowplow/schemas.md b/doc/development/snowplow/schemas.md
index 63864c9329b..4066151600d 100644
--- a/doc/development/snowplow/schemas.md
+++ b/doc/development/snowplow/schemas.md
@@ -10,17 +10,18 @@ This page provides Snowplow schema reference for GitLab events.
## `gitlab_standard`
-We are including the [`gitlab_standard` schema](https://gitlab.com/gitlab-org/iglu/-/blob/master/public/schemas/com.gitlab/gitlab_standard/jsonschema/) with every event. See [Standardize Snowplow Schema](https://gitlab.com/groups/gitlab-org/-/epics/5218) for details.
+We are including the [`gitlab_standard` schema](https://gitlab.com/gitlab-org/iglu/-/blob/master/public/schemas/com.gitlab/gitlab_standard/jsonschema/) for structured events and page views.
The [`StandardContext`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/tracking/standard_context.rb)
-class represents this schema in the application. Some properties are automatically populated for [frontend](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/views/layouts/_snowplow.html.haml)
-events.
+class represents this schema in the application. Some properties are
+[automatically populated for frontend events](implementation.md#snowplow-javascript-frontend-tracking),
+and can be [provided manually for backend events](implementation.md#implement-ruby-backend-tracking).
| Field Name | Required | Default value | Type | Description |
|----------------|:-------------------:|-----------------------|--|---------------------------------------------------------------------------------------------|
| `project_id` | **{dotted-circle}** | Current project ID * | integer | |
| `namespace_id` | **{dotted-circle}** | Current group/namespace ID * | integer | |
-| `user_id` | **{dotted-circle}** | Current user ID * | integer | User database record ID attribute. This file undergoes a pseudonymization process at the collector level. |
+| `user_id` | **{dotted-circle}** | Current user ID * | integer | User database record ID attribute. This value undergoes a pseudonymization process at the collector level. |
| `context_generated_at` | **{dotted-circle}** | Current timestamp | string (date time format) | Timestamp indicating when context was generated. |
| `environment` | **{check-circle}** | Current environment | string (max 32 chars) | Name of the source environment, such as `production` or `staging` |
| `source` | **{check-circle}** | Event source | string (max 32 chars) | Name of the source application, such as `gitlab-rails` or `gitlab-javascript` |
diff --git a/doc/user/clusters/agent/ci_cd_tunnel.md b/doc/user/clusters/agent/ci_cd_tunnel.md
index 8737206d87f..c15041f6b0d 100644
--- a/doc/user/clusters/agent/ci_cd_tunnel.md
+++ b/doc/user/clusters/agent/ci_cd_tunnel.md
@@ -70,6 +70,7 @@ To authorize the agent to access the GitLab project where you keep Kubernetes ma
```
- The Kubernetes projects must be in the same group hierarchy as the project where the agent's configuration is.
+ - You can install additional agents into the same cluster to accommodate additional hierarchies.
- You can authorize up to 100 projects.
All CI/CD jobs now include a `KUBECONFIG` with contexts for every shared agent connection.
@@ -92,9 +93,11 @@ To authorize the agent to access all of the GitLab projects in a group or subgro
```
- The Kubernetes projects must be in the same group hierarchy as the project where the agent's configuration is.
+ - You can install additional agents into the same cluster to accommodate additional hierarchies.
+ - All of the subgroups of an authorized group also have access to the same agent (without being specified individually).
- You can authorize up to 100 groups.
-All the projects that belong to the group are now authorized to access the agent.
+All the projects that belong to the group and its subgroups are now authorized to access the agent.
All CI/CD jobs now include a `KUBECONFIG` with contexts for every shared agent connection.
Choose the context to run `kubectl` commands from your CI/CD scripts.
diff --git a/doc/user/clusters/agent/index.md b/doc/user/clusters/agent/index.md
index c6193e8f388..bab3f3137fe 100644
--- a/doc/user/clusters/agent/index.md
+++ b/doc/user/clusters/agent/index.md
@@ -43,8 +43,8 @@ This workflow is considered push-based, because GitLab is pushing requests from
GitLab supports the following Kubernetes versions. You can upgrade your
Kubernetes version to a supported version at any time:
+- 1.21 (support ends on November 22, 2022)
- 1.20 (support ends on July 22, 2022)
-- 1.19 (support ends on February 22, 2022)
GitLab supports at least two production-ready Kubernetes minor
versions at any given time. GitLab regularly reviews the supported versions and
diff --git a/doc/user/project/code_owners.md b/doc/user/project/code_owners.md
index 37771fb4762..e37ff560080 100644
--- a/doc/user/project/code_owners.md
+++ b/doc/user/project/code_owners.md
@@ -254,6 +254,11 @@ README @group @group/with-nested/subgroup
# `docs/index.md` but not `docs/projects/index.md`:
/docs/* @root-docs
+# Include `/**` to specify Code Owners for all subdirectories
+# in a directory. This rule matches `docs/projects/index.md` or
+# `docs/development/index.md`
+/docs/**/*.md @root-docs
+
# This code makes matches a `lib` directory nested anywhere in the repository:
lib/ @lib-owner