diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml
index 559d0749c96..eedfea994c4 100644
--- a/.gitlab/ci/docs.gitlab-ci.yml
+++ b/.gitlab/ci/docs.gitlab-ci.yml
@@ -71,6 +71,7 @@ ui-docs-links lint:
extends:
- .docs:rules:docs-lint
- .static-analysis-base
+ - .ruby-cache
stage: lint
needs: []
script:
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index 9aa9aadd8c0..ae55f771fa4 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -2558,7 +2558,6 @@ Rails/IncludeUrlHelper:
# TODO issue: https://gitlab.com/gitlab-org/gitlab/-/issues/344279
Style/OpenStructUse:
Exclude:
- - 'Guardfile'
- 'app/finders/snippets_finder.rb'
- 'app/helpers/application_settings_helper.rb'
- 'ee/lib/gitlab/graphql/aggregations/epics/epic_node.rb'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52d66b1ab22..6c670421d88 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3066,18 +3066,18 @@ No changes.
## 13.12.15 (2021-11-03)
-No changes.
-
-## 13.12.14 (2021-11-03)
-
### Fixed (2 changes)
- [Allow nil for remaining ci cd settings](gitlab-org/gitlab@896fd7ecf23714fa9f710efa4af245a26c677dce) ([merge request](gitlab-org/gitlab!73522))
- [Allow nil on delegated CI/CD settings](gitlab-org/gitlab@d57a9ea79080fc473eb54c0ee696a50fd270e8a4) ([merge request](gitlab-org/gitlab!73522))
+## 13.12.14 (2021-11-03)
+
+This version has been skipped due to QA problems.
+
## 13.12.13 (2021-10-29)
-No changes.
+This version has been skipped due to QA problems.
## 13.12.12 (2021-09-21)
diff --git a/Guardfile b/Guardfile
index 1d9ec406c1d..66a689ed978 100644
--- a/Guardfile
+++ b/Guardfile
@@ -9,7 +9,7 @@ cmd = ENV['GUARD_CMD'] || (ENV['SPRING'] ? 'spring rspec' : 'bundle exec rspec')
directories %w(app ee lib rubocop tooling spec)
rspec_context_for = proc do |context_path|
- OpenStruct.new(to_s: "spec").tap do |rspec|
+ OpenStruct.new(to_s: "spec").tap do |rspec| # rubocop:disable Style/OpenStructUse
rspec.spec_dir = "#{context_path}spec"
rspec.spec = ->(m) { Guard::RSpec::Dsl.detect_spec_file_for(rspec, m) }
rspec.spec_helper = "#{rspec.spec_dir}/spec_helper.rb"
@@ -19,7 +19,7 @@ rspec_context_for = proc do |context_path|
end
rails_context_for = proc do |context_path, exts|
- OpenStruct.new.tap do |rails|
+ OpenStruct.new.tap do |rails| # rubocop:disable Style/OpenStructUse
rails.app_files = %r{^#{context_path}app/(.+)\.rb$}
rails.views = %r{^#{context_path}app/(views/.+/[^/]*\.(?:#{exts}))$}
diff --git a/app/graphql/types/evidence_type.rb b/app/graphql/types/evidence_type.rb
index 26fb64d25d8..33f46c712f1 100644
--- a/app/graphql/types/evidence_type.rb
+++ b/app/graphql/types/evidence_type.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'ReleaseEvidence'
description 'Evidence for a release'
- authorize :download_code
+ authorize :read_release_evidence
present_using Releases::EvidencePresenter
diff --git a/app/graphql/types/packages/file_metadata_type.rb b/app/graphql/types/packages/file_metadata_type.rb
index 46ccb424218..0731fc897a2 100644
--- a/app/graphql/types/packages/file_metadata_type.rb
+++ b/app/graphql/types/packages/file_metadata_type.rb
@@ -14,6 +14,8 @@ module Types
case object
when ::Packages::Conan::FileMetadatum
::Types::Packages::Conan::FileMetadatumType
+ when ::Packages::Helm::FileMetadatum
+ ::Types::Packages::Helm::FileMetadatumType
else
# NOTE: This method must be kept in sync with `PackageFileType#file_metadata`,
# which must never produce data that this discriminator cannot handle.
@@ -21,7 +23,8 @@ module Types
end
end
- orphan_types Types::Packages::Conan::FileMetadatumType
+ orphan_types Types::Packages::Conan::FileMetadatumType,
+ Types::Packages::Helm::FileMetadatumType
end
end
end
diff --git a/app/graphql/types/packages/helm/dependency_type.rb b/app/graphql/types/packages/helm/dependency_type.rb
new file mode 100644
index 00000000000..35598c2b1d7
--- /dev/null
+++ b/app/graphql/types/packages/helm/dependency_type.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Types
+ module Packages
+ module Helm
+ # rubocop: disable Graphql/AuthorizeTypes
+ class DependencyType < BaseObject
+ graphql_name 'PackageHelmDependencyType'
+ description 'Represents a Helm dependency'
+
+ # Need to be synced with app/validators/json_schemas/helm_metadata.json#dependencies
+ field :name, GraphQL::Types::String, null: true, description: 'Name of the dependency.'
+ field :version, GraphQL::Types::String, null: true, description: 'Version of the dependency.'
+ field :repository, GraphQL::Types::String, null: true, description: 'Repository of the dependency.'
+ field :condition, GraphQL::Types::String, null: true, description: 'Condition of the dependency.'
+ field :tags, [GraphQL::Types::String], null: true, description: 'Tags of the dependency.'
+ field :enabled, GraphQL::Types::Boolean, null: true, description: 'Indicates the dependency is enabled.'
+ field :import_values, [GraphQL::Types::JSON], null: true, description: 'Import-values of the dependency.', hash_key: "import-values" # rubocop:disable Graphql/JSONType
+ field :alias, GraphQL::Types::String, null: true, description: 'Alias of the dependency.', resolver_method: :resolve_alias
+
+ # field :alias` conflicts with a built-in method
+ def resolve_alias
+ object['alias']
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/packages/helm/file_metadatum_type.rb b/app/graphql/types/packages/helm/file_metadatum_type.rb
new file mode 100644
index 00000000000..734ed52df40
--- /dev/null
+++ b/app/graphql/types/packages/helm/file_metadatum_type.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Types
+ module Packages
+ module Helm
+ class FileMetadatumType < BaseObject
+ graphql_name 'HelmFileMetadata'
+ description 'Helm file metadata'
+
+ implements Types::Packages::FileMetadataType
+
+ authorize :read_package
+
+ field :channel, GraphQL::Types::String, null: false, description: 'Channel of the Helm chart.'
+ field :metadata, Types::Packages::Helm::MetadataType, null: false, description: 'Metadata of the Helm chart.'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/packages/helm/maintainer_type.rb b/app/graphql/types/packages/helm/maintainer_type.rb
new file mode 100644
index 00000000000..6d25a26c46b
--- /dev/null
+++ b/app/graphql/types/packages/helm/maintainer_type.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Types
+ module Packages
+ module Helm
+ # rubocop: disable Graphql/AuthorizeTypes
+ class MaintainerType < BaseObject
+ graphql_name 'PackageHelmMaintainerType'
+ description 'Represents a Helm maintainer'
+
+ # Need to be synced with app/validators/json_schemas/helm_metadata.json#maintainers
+ field :name, GraphQL::Types::String, null: true, description: 'Name of the maintainer.'
+ field :email, GraphQL::Types::String, null: true, description: 'Email of the maintainer.'
+ field :url, GraphQL::Types::String, null: true, description: 'URL of the maintainer.'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/packages/helm/metadata_type.rb b/app/graphql/types/packages/helm/metadata_type.rb
new file mode 100644
index 00000000000..eeb3e8087a8
--- /dev/null
+++ b/app/graphql/types/packages/helm/metadata_type.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Types
+ module Packages
+ module Helm
+ # rubocop: disable Graphql/AuthorizeTypes
+ class MetadataType < BaseObject
+ graphql_name 'PackageHelmMetadataType'
+ description 'Represents the contents of a Helm Chart.yml file'
+
+ # Need to be synced with app/validators/json_schemas/helm_metadata.json
+ field :name, GraphQL::Types::String, null: false, description: 'Name of the chart.'
+ field :home, GraphQL::Types::String, null: true, description: 'URL of the home page.'
+ field :sources, [GraphQL::Types::String], null: true, description: 'URLs of the source code for the chart.'
+ field :version, GraphQL::Types::String, null: false, description: 'Version of the chart.'
+ field :description, GraphQL::Types::String, null: true, description: 'Description of the chart.'
+ field :keywords, [GraphQL::Types::String], null: true, description: 'Keywords for the chart.'
+ field :maintainers, [Types::Packages::Helm::MaintainerType], null: true, description: 'Maintainers of the chart.'
+ field :icon, GraphQL::Types::String, null: true, description: 'URL to an SVG or PNG image for the chart.'
+ field :api_version, GraphQL::Types::String, null: false, description: 'API version of the chart.', hash_key: "apiVersion"
+ field :condition, GraphQL::Types::String, null: true, description: 'Condition for the chart.'
+ field :tags, GraphQL::Types::String, null: true, description: 'Tags for the chart.'
+ field :app_version, GraphQL::Types::String, null: true, description: 'App version of the chart.', hash_key: "appVersion"
+ field :deprecated, GraphQL::Types::Boolean, null: true, description: 'Indicates if the chart is deprecated.'
+ field :annotations, GraphQL::Types::JSON, null: true, description: 'Annotations for the chart.' # rubocop:disable Graphql/JSONType
+ field :kube_version, GraphQL::Types::String, null: true, description: 'Kubernetes versions for the chart.', hash_key: "kubeVersion"
+ field :dependencies, [Types::Packages::Helm::DependencyType], null: true, description: 'Dependencies of the chart.'
+ field :type, GraphQL::Types::String, null: true, description: 'Type of the chart.', hash_key: "appVersion"
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/packages/package_file_type.rb b/app/graphql/types/packages/package_file_type.rb
index 8cc0f9b984a..f90a0992bf8 100644
--- a/app/graphql/types/packages/package_file_type.rb
+++ b/app/graphql/types/packages/package_file_type.rb
@@ -27,6 +27,8 @@ module Types
case object.package.package_type
when 'conan'
object.conan_file_metadatum
+ when 'helm'
+ object.helm_file_metadatum
else
nil
end
diff --git a/app/policies/packages/helm/file_metadatum_policy.rb b/app/policies/packages/helm/file_metadatum_policy.rb
new file mode 100644
index 00000000000..4e0cb9046bf
--- /dev/null
+++ b/app/policies/packages/helm/file_metadatum_policy.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+module Packages
+ module Helm
+ class FileMetadatumPolicy < BasePolicy
+ delegate { @subject.package_file.package }
+ end
+ end
+end
diff --git a/app/validators/json_schemas/helm_metadata.json b/app/validators/json_schemas/helm_metadata.json
index 7ac36e956f3..a5ff6f0b33a 100644
--- a/app/validators/json_schemas/helm_metadata.json
+++ b/app/validators/json_schemas/helm_metadata.json
@@ -103,7 +103,23 @@
"import-values": {
"type": "array",
"items": {
-
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "child": {
+ "type": "string"
+ },
+ "parent": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ ]
}
},
"alias": {
diff --git a/config/feature_flags/development/linear_ee_group_ancestor_scopes.yml b/config/feature_flags/development/linear_ee_group_ancestor_scopes.yml
deleted file mode 100644
index 46294b0aef0..00000000000
--- a/config/feature_flags/development/linear_ee_group_ancestor_scopes.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: linear_ee_group_ancestor_scopes
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70708
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341350
-milestone: '14.4'
-type: development
-group: group::access
-default_enabled: false
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 4b09907b9a8..ba199b01c56 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -10911,6 +10911,19 @@ Represents the Geo sync and verification state of a group wiki repository.
| `retryCount` | [`Int`](#int) | Number of consecutive failed sync attempts of the GroupWikiRepositoryRegistry. |
| `state` | [`RegistryState`](#registrystate) | Sync state of the GroupWikiRepositoryRegistry. |
+### `HelmFileMetadata`
+
+Helm file metadata.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `channel` | [`String!`](#string) | Channel of the Helm chart. |
+| `createdAt` | [`Time!`](#time) | Date of creation. |
+| `metadata` | [`PackageHelmMetadataType!`](#packagehelmmetadatatype) | Metadata of the Helm chart. |
+| `updatedAt` | [`Time!`](#time) | Date of most recent update. |
+
### `IncidentManagementOncallRotation`
Describes an incident management on-call rotation.
@@ -12381,6 +12394,61 @@ Represents the Geo sync and verification state of a package file.
| `retryCount` | [`Int`](#int) | Number of consecutive failed sync attempts of the PackageFileRegistry. |
| `state` | [`RegistryState`](#registrystate) | Sync state of the PackageFileRegistry. |
+### `PackageHelmDependencyType`
+
+Represents a Helm dependency.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `alias` | [`String`](#string) | Alias of the dependency. |
+| `condition` | [`String`](#string) | Condition of the dependency. |
+| `enabled` | [`Boolean`](#boolean) | Indicates the dependency is enabled. |
+| `importValues` | [`[JSON!]`](#json) | Import-values of the dependency. |
+| `name` | [`String`](#string) | Name of the dependency. |
+| `repository` | [`String`](#string) | Repository of the dependency. |
+| `tags` | [`[String!]`](#string) | Tags of the dependency. |
+| `version` | [`String`](#string) | Version of the dependency. |
+
+### `PackageHelmMaintainerType`
+
+Represents a Helm maintainer.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `email` | [`String`](#string) | Email of the maintainer. |
+| `name` | [`String`](#string) | Name of the maintainer. |
+| `url` | [`String`](#string) | URL of the maintainer. |
+
+### `PackageHelmMetadataType`
+
+Represents the contents of a Helm Chart.yml file.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `annotations` | [`JSON`](#json) | Annotations for the chart. |
+| `apiVersion` | [`String!`](#string) | API version of the chart. |
+| `appVersion` | [`String`](#string) | App version of the chart. |
+| `condition` | [`String`](#string) | Condition for the chart. |
+| `dependencies` | [`[PackageHelmDependencyType!]`](#packagehelmdependencytype) | Dependencies of the chart. |
+| `deprecated` | [`Boolean`](#boolean) | Indicates if the chart is deprecated. |
+| `description` | [`String`](#string) | Description of the chart. |
+| `home` | [`String`](#string) | URL of the home page. |
+| `icon` | [`String`](#string) | URL to an SVG or PNG image for the chart. |
+| `keywords` | [`[String!]`](#string) | Keywords for the chart. |
+| `kubeVersion` | [`String`](#string) | Kubernetes versions for the chart. |
+| `maintainers` | [`[PackageHelmMaintainerType!]`](#packagehelmmaintainertype) | Maintainers of the chart. |
+| `name` | [`String!`](#string) | Name of the chart. |
+| `sources` | [`[String!]`](#string) | URLs of the source code for the chart. |
+| `tags` | [`String`](#string) | Tags for the chart. |
+| `type` | [`String`](#string) | Type of the chart. |
+| `version` | [`String!`](#string) | Version of the chart. |
+
### `PackageSettings`
Namespace-level Package Registry settings.
@@ -17759,6 +17827,7 @@ Represents metadata associated with a Package file.
Implementations:
- [`ConanFileMetadata`](#conanfilemetadata)
+- [`HelmFileMetadata`](#helmfilemetadata)
##### Fields
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 01e61679c0d..40bc41fa7e1 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -1652,10 +1652,12 @@ docker build:
- docker/scripts/*
- dockerfiles/**/*
- more_scripts/*.{rb,py,sh}
+ - "**/*.json"
```
**Additional details**:
+- If any of the matching files are changed (an `OR` operation), `changes` resolves to `true`.
- If you use refs other than `branches`, `external_pull_requests`, or `merge_requests`,
`changes` can't determine if a given file is new or old and always returns `true`.
- If you use `only: changes` with other refs, jobs ignore the changes and always run.
diff --git a/doc/development/gemfile.md b/doc/development/gemfile.md
index e071aa4ffd9..221c8dfbf9d 100644
--- a/doc/development/gemfile.md
+++ b/doc/development/gemfile.md
@@ -55,7 +55,7 @@ to a gem, go through these steps:
- For an example, see the [merge request !57805](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57805).
1. Once the gem is stable - we have been using it in production for a
while with few, if any, changes - extract to its own project under
- the `gitlab-org` namespace.
+ the [`gitlab-org/ruby/gems` namespace](https://gitlab.com/gitlab-org/ruby/gems/).
1. When creating the project, follow the [instructions for new projects](https://about.gitlab.com/handbook/engineering/#creating-a-new-project).
1. Follow the instructions for setting up a [CI/CD configuration](https://about.gitlab.com/handbook/engineering/#cicd-configuration).
1. Follow the instructions for [publishing a project](https://about.gitlab.com/handbook/engineering/#publishing-a-project).
diff --git a/doc/development/go_guide/go_upgrade.md b/doc/development/go_guide/go_upgrade.md
index 75a093a55ac..53f2d7d176a 100644
--- a/doc/development/go_guide/go_upgrade.md
+++ b/doc/development/go_guide/go_upgrade.md
@@ -89,10 +89,14 @@ if you need help finding the correct person or labels:
1. Schedule an update with the [GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit/-/issues):
- Title the issue `Support using Go version `.
- Set the issue as related to every issue created in the previous step.
-1. Schedule one issue per Secure Stage team and add the `devops::secure` label to each:
+1. Schedule one issue per Sec Section team that maintains Go based Security Analyzers and add the `section::sec` label to each:
- [Static Analysis tracker](https://gitlab.com/gitlab-org/gitlab/-/issues).
- [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.
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 ` and description as noted:
diff --git a/doc/development/secure_coding_guidelines.md b/doc/development/secure_coding_guidelines.md
index 765370e35ec..98293eb21f7 100644
--- a/doc/development/secure_coding_guidelines.md
+++ b/doc/development/secure_coding_guidelines.md
@@ -540,6 +540,94 @@ out, _ = exec.Command("sh", "-c", "echo 1 | cat /etc/passwd").Output()
This outputs `1` followed by the content of `/etc/passwd`.
+## General recommendations
+
+### TLS minimum recommended version
+
+As we have [moved away from supporting TLS 1.0 and 1.1](https://about.gitlab.com/blog/2018/10/15/gitlab-to-deprecate-older-tls/), we should only use TLS 1.2 and above.
+
+#### Ciphers
+
+We recommend using the ciphers that Mozilla is providing in their [recommended SSL configuration generator](https://ssl-config.mozilla.org/#server=go&version=1.17&config=intermediate&guideline=5.6) for TLS 1.2:
+
+- `ECDHE-ECDSA-AES128-GCM-SHA256`
+- `ECDHE-RSA-AES128-GCM-SHA256`
+- `ECDHE-ECDSA-AES256-GCM-SHA384`
+- `ECDHE-RSA-AES256-GCM-SHA384`
+- `ECDHE-ECDSA-CHACHA20-POLY1305`
+- `ECDHE-RSA-CHACHA20-POLY1305`
+
+And the following cipher suites (according to the [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446#appendix-B.4)) for TLS 1.3:
+
+- `TLS_AES_128_GCM_SHA256`
+- `TLS_AES_256_GCM_SHA384`
+- `TLS_CHACHA20_POLY1305_SHA256`
+
+*Note*: **Golang** does [not support](https://github.com/golang/go/blob/go1.17/src/crypto/tls/cipher_suites.go#L676) all cipher suites with TLS 1.3.
+
+##### Implementation examples
+
+##### TLS 1.3
+
+For TLS 1.3, **Golang** only supports [3 cipher suites](https://github.com/golang/go/blob/go1.17/src/crypto/tls/cipher_suites.go#L676), as such we only need to set the TLS version:
+
+```golang
+cfg := &tls.Config{
+ MinVersion: tls.VersionTLS13,
+}
+```
+
+For **Ruby**, you can use [HTTParty](https://github.com/jnunemaker/httparty) and specify TLS 1.3 version as well as ciphers:
+
+Whenever possible this example should be **avoided** for security purposes:
+
+```ruby
+response = HTTParty.get('https://gitlab.com', ssl_version: :TLSv1_3, ciphers: ['TLS_AES_128_GCM_SHA256', 'TLS_AES_256_GCM_SHA384', 'TLS_CHACHA20_POLY1305_SHA256'])
+```
+
+When using [`GitLab::HTTP`](#gitlab-http-library), the code looks like:
+
+This is the **recommended** implementation to avoid security issues such as SSRF:
+
+```ruby
+response = GitLab::HTTP.perform_request(Net::HTTP::Get, 'https://gitlab.com', ssl_version: :TLSv1_3, ciphers: ['TLS_AES_128_GCM_SHA256', 'TLS_AES_256_GCM_SHA384', 'TLS_CHACHA20_POLY1305_SHA256'])
+```
+
+##### TLS 1.2
+
+**Golang** does support multiple cipher suites that we do not want to use with TLS 1.2. We need to explicitly list authorised ciphers:
+
+```golang
+func secureCipherSuites() []uint16 {
+ return []uint16{
+ tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+ tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ }
+```
+
+And then use `secureCipherSuites()` in `tls.Config`:
+
+```golang
+tls.Config{
+ (...),
+ CipherSuites: secureCipherSuites(),
+ MinVersion: tls.VersionTLS12,
+ (...),
+}
+```
+
+This example was taken [here](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/871b52dc700f1a66f6644fbb1e78a6d463a6ff83/internal/tool/tlstool/tlstool.go#L72).
+
+For **Ruby**, you can use again [HTTParty](https://github.com/jnunemaker/httparty) and specify this time TLS 1.2 version alongside with the recommended ciphers:
+
+```ruby
+response = GitLab::HTTP.perform_request(Net::HTTP::Get, 'https://gitlab.com', ssl_version: :TLSv1_2, ciphers: ['ECDHE-ECDSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-ECDSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-ECDSA-CHACHA20-POLY1305', 'ECDHE-RSA-CHACHA20-POLY1305'])
+```
+
## GitLab Internal Authorization
### Introduction
diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md
index 88785196f6e..70e3115a98e 100644
--- a/doc/operations/error_tracking.md
+++ b/doc/operations/error_tracking.md
@@ -169,5 +169,6 @@ You can do so by managing client keys with the [error tracking API](../api/error
#### Limitations
-The Integrated Error Tracking feature was built and tested with Sentry SDK for Ruby. Other languages and frameworks
-are not tested and might not work. Check [the compatibility issue](https://gitlab.com/gitlab-org/gitlab/-/issues/340178) for more information.
+The Integrated Error Tracking feature was built and tested with Sentry SDK for Ruby on Rails.
+Support for other languages and frameworks is not guaranteed. For up-to-date information, see the
+[compatibility issue](https://gitlab.com/gitlab-org/gitlab/-/issues/340178).
diff --git a/doc/user/clusters/management_project_template.md b/doc/user/clusters/management_project_template.md
index 305f66c5ec5..ea364063758 100644
--- a/doc/user/clusters/management_project_template.md
+++ b/doc/user/clusters/management_project_template.md
@@ -109,6 +109,6 @@ The [built-in supported applications](https://gitlab.com/gitlab-org/project-temp
#### How to customize your applications
-Each app has an `applications/{app}/values.yaml` file (`applicaton/{app}/values.yaml.gotmpl` in case of GitLab Runner). This is the
+Each app has an `applications/{app}/values.yaml` file (`applications/{app}/values.yaml.gotmpl` in case of GitLab Runner). This is the
place where you can define default values for your app's Helm chart. Some apps already have defaults
pre-defined by GitLab.
diff --git a/lib/api/ci/jobs.rb b/lib/api/ci/jobs.rb
index 7c9c4a7af12..30ce1454419 100644
--- a/lib/api/ci/jobs.rb
+++ b/lib/api/ci/jobs.rb
@@ -190,14 +190,25 @@ module API
pipeline = current_authenticated_job.pipeline
project = current_authenticated_job.project
agent_authorizations = Clusters::AgentAuthorizationsFinder.new(project).execute
+ project_groups = project.group&.self_and_ancestor_ids&.map { |id| { id: id } } || []
+ user_access_level = project.team.max_member_access(current_user.id)
+ roles_in_project = Gitlab::Access.sym_options_with_owner
+ .select { |_role, role_access_level| role_access_level <= user_access_level }
+ .map(&:first)
+ environment = if environment_slug = current_authenticated_job.deployment&.environment&.slug
+ { slug: environment_slug }
+ end
+
+ # See https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kubernetes_ci_access.md#apiv4joballowed_agents-api
{
allowed_agents: Entities::Clusters::AgentAuthorization.represent(agent_authorizations),
- job: Entities::Ci::JobRequest::JobInfo.represent(current_authenticated_job),
- pipeline: Entities::Ci::PipelineBasic.represent(pipeline),
- project: Entities::ProjectIdentity.represent(project),
- user: Entities::UserBasic.represent(current_user)
- }
+ job: { id: current_authenticated_job.id },
+ pipeline: { id: pipeline.id },
+ project: { id: project.id, groups: project_groups },
+ user: { id: current_user.id, username: current_user.username, roles_in_project: roles_in_project },
+ environment: environment
+ }.compact
end
end
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index 4cd5e999027..30871a16e4e 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -44,7 +44,7 @@ module Gitlab
new_blob_lazy
old_blob_lazy
- preprocess_before_diff(diff) if Feature.enabled?(:jupyter_clean_diffs, @project)
+ preprocess_before_diff(diff) if Feature.enabled?(:jupyter_clean_diffs, repository.project)
end
def position(position_marker, position_type: :text)
diff --git a/spec/factories/packages/helm/file_metadatum.rb b/spec/factories/packages/helm/file_metadatum.rb
index 3f599b5d5c0..590956e5d49 100644
--- a/spec/factories/packages/helm/file_metadatum.rb
+++ b/spec/factories/packages/helm/file_metadatum.rb
@@ -9,7 +9,11 @@ FactoryBot.define do
package_file { association(:helm_package_file, without_loaded_metadatum: true) }
sequence(:channel) { |n| "#{FFaker::Lorem.word}-#{n}" }
metadata do
- { 'name': package_file.package.name, 'version': package_file.package.version, 'apiVersion': 'v2' }.tap do |defaults|
+ {
+ 'name': package_file.package.name,
+ 'version': package_file.package.version,
+ 'apiVersion': 'v2'
+ }.tap do |defaults|
defaults['description'] = description if description
end
end
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index 63c36a20adc..76cec2502e3 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -146,8 +146,7 @@ RSpec.describe "Issues > User edits issue", :js do
fill_in 'Comment', with: '/label ~syzygy'
click_button 'Comment'
-
- wait_for_requests
+ expect(page).to have_text('added syzygy label just now')
page.within '.block.labels' do
# Remove `verisimilitude` label
@@ -155,8 +154,6 @@ RSpec.describe "Issues > User edits issue", :js do
click_button
end
- wait_for_requests
-
expect(page).to have_text('syzygy')
expect(page).not_to have_text('verisimilitude')
end
diff --git a/spec/fixtures/api/schemas/graphql/packages/package_details.json b/spec/fixtures/api/schemas/graphql/packages/package_details.json
index 2824ca64325..9ef7f6c9271 100644
--- a/spec/fixtures/api/schemas/graphql/packages/package_details.json
+++ b/spec/fixtures/api/schemas/graphql/packages/package_details.json
@@ -12,7 +12,6 @@
"tags",
"pipelines",
"versions",
- "metadata",
"status",
"canDestroy"
],
@@ -47,7 +46,8 @@
"GENERIC",
"GOLANG",
"RUBYGEMS",
- "DEBIAN"
+ "DEBIAN",
+ "HELM"
]
},
"tags": {
diff --git a/spec/graphql/types/evidence_type_spec.rb b/spec/graphql/types/evidence_type_spec.rb
index 92134e74d51..be85724eac5 100644
--- a/spec/graphql/types/evidence_type_spec.rb
+++ b/spec/graphql/types/evidence_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['ReleaseEvidence'] do
- it { expect(described_class).to require_graphql_authorizations(:download_code) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_release_evidence) }
it 'has the expected fields' do
expected_fields = %w[
diff --git a/spec/graphql/types/packages/helm/dependency_type_spec.rb b/spec/graphql/types/packages/helm/dependency_type_spec.rb
new file mode 100644
index 00000000000..2047205275f
--- /dev/null
+++ b/spec/graphql/types/packages/helm/dependency_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['PackageHelmDependencyType'] do
+ it { expect(described_class.graphql_name).to eq('PackageHelmDependencyType') }
+
+ it 'includes helm dependency fields' do
+ expected_fields = %w[
+ name version repository condition tags enabled import_values alias
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/packages/helm/file_metadatum_type_spec.rb b/spec/graphql/types/packages/helm/file_metadatum_type_spec.rb
new file mode 100644
index 00000000000..b7bcd6213b4
--- /dev/null
+++ b/spec/graphql/types/packages/helm/file_metadatum_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['HelmFileMetadata'] do
+ it { expect(described_class.graphql_name).to eq('HelmFileMetadata') }
+
+ it 'includes helm file metadatum fields' do
+ expected_fields = %w[
+ created_at updated_at channel metadata
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/packages/helm/maintainer_type_spec.rb b/spec/graphql/types/packages/helm/maintainer_type_spec.rb
new file mode 100644
index 00000000000..9ad51427d42
--- /dev/null
+++ b/spec/graphql/types/packages/helm/maintainer_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['PackageHelmMaintainerType'] do
+ it { expect(described_class.graphql_name).to eq('PackageHelmMaintainerType') }
+
+ it 'includes helm maintainer fields' do
+ expected_fields = %w[
+ name email url
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/packages/helm/metadata_type_spec.rb b/spec/graphql/types/packages/helm/metadata_type_spec.rb
new file mode 100644
index 00000000000..04639450d9a
--- /dev/null
+++ b/spec/graphql/types/packages/helm/metadata_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['PackageHelmMetadataType'] do
+ it { expect(described_class.graphql_name).to eq('PackageHelmMetadataType') }
+
+ it 'includes helm json fields' do
+ expected_fields = %w[
+ name home sources version description keywords maintainers icon apiVersion condition tags appVersion deprecated annotations kubeVersion dependencies type
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/requests/api/ci/jobs_spec.rb b/spec/requests/api/ci/jobs_spec.rb
index a1a0086d96b..580f3d9e92d 100644
--- a/spec/requests/api/ci/jobs_spec.rb
+++ b/spec/requests/api/ci/jobs_spec.rb
@@ -177,11 +177,16 @@ RSpec.describe API::Ci::Jobs do
end
describe 'GET /job/allowed_agents' do
- let_it_be(:group_authorization) { create(:agent_group_authorization) }
- let_it_be(:associated_agent) { create(:cluster_agent, project: project) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:group_agent) { create(:cluster_agent, project: create(:project, group: group)) }
+ let_it_be(:group_authorization) { create(:agent_group_authorization, agent: group_agent, group: group) }
+ let_it_be(:project_agent) { create(:cluster_agent, project: project) }
- let(:implicit_authorization) { Clusters::Agents::ImplicitAuthorization.new(agent: associated_agent) }
- let(:authorizations_finder) { double(execute: [implicit_authorization, group_authorization]) }
+ before(:all) do
+ project.update!(group: group_authorization.group)
+ end
+
+ let(:implicit_authorization) { Clusters::Agents::ImplicitAuthorization.new(agent: project_agent) }
let(:headers) { { API::Ci::Helpers::Runner::JOB_TOKEN_HEADER => job.token } }
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline, user: api_user, status: job_status) }
@@ -193,44 +198,22 @@ RSpec.describe API::Ci::Jobs do
end
before do
- allow(Clusters::AgentAuthorizationsFinder).to receive(:new).with(project).and_return(authorizations_finder)
-
subject
end
context 'when token is valid and user is authorized' do
- it 'returns agent info', :aggregate_failures do
- expect(response).to have_gitlab_http_status(:ok)
-
- expect(json_response.dig('job', 'id')).to eq(job.id)
- expect(json_response.dig('pipeline', 'id')).to eq(job.pipeline_id)
- expect(json_response.dig('project', 'id')).to eq(job.project_id)
- expect(json_response.dig('user', 'username')).to eq(api_user.username)
- expect(json_response['allowed_agents']).to match_array([
- {
- 'id' => implicit_authorization.agent_id,
- 'config_project' => hash_including('id' => implicit_authorization.agent.project_id),
- 'configuration' => implicit_authorization.config
- },
- {
- 'id' => group_authorization.agent_id,
- 'config_project' => hash_including('id' => group_authorization.agent.project_id),
- 'configuration' => group_authorization.config
- }
- ])
- end
-
- context 'when passing the token as params' do
- let(:headers) { {} }
- let(:params) { { job_token: job.token } }
-
+ shared_examples_for 'valid allowed_agents request' do
it 'returns agent info', :aggregate_failures do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.dig('job', 'id')).to eq(job.id)
expect(json_response.dig('pipeline', 'id')).to eq(job.pipeline_id)
expect(json_response.dig('project', 'id')).to eq(job.project_id)
+ expect(json_response.dig('project', 'groups')).to match_array([{ 'id' => group_authorization.group.id }])
+ expect(json_response.dig('user', 'id')).to eq(api_user.id)
expect(json_response.dig('user', 'username')).to eq(api_user.username)
+ expect(json_response.dig('user', 'roles_in_project')).to match_array %w(guest reporter developer)
+ expect(json_response).not_to include('environment')
expect(json_response['allowed_agents']).to match_array([
{
'id' => implicit_authorization.agent_id,
@@ -239,12 +222,29 @@ RSpec.describe API::Ci::Jobs do
},
{
'id' => group_authorization.agent_id,
- 'config_project' => a_hash_including('id' => group_authorization.agent.project_id),
+ 'config_project' => hash_including('id' => group_authorization.agent.project_id),
'configuration' => group_authorization.config
}
])
end
end
+
+ it_behaves_like 'valid allowed_agents request'
+
+ context 'when deployment' do
+ let(:job) { create(:ci_build, :artifacts, :with_deployment, environment: 'production', pipeline: pipeline, user: api_user, status: job_status) }
+
+ it 'includes environment slug' do
+ expect(json_response.dig('environment', 'slug')).to eq('production')
+ end
+ end
+
+ context 'when passing the token as params' do
+ let(:headers) { {} }
+ let(:params) { { job_token: job.token } }
+
+ it_behaves_like 'valid allowed_agents request'
+ end
end
context 'when user is anonymous' do
diff --git a/spec/requests/api/graphql/packages/helm_spec.rb b/spec/requests/api/graphql/packages/helm_spec.rb
new file mode 100644
index 00000000000..397096f70db
--- /dev/null
+++ b/spec/requests/api/graphql/packages/helm_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'helm package details' do
+ include GraphqlHelpers
+ include_context 'package details setup'
+
+ let_it_be(:package) { create(:helm_package, project: project) }
+
+ let(:package_files_metadata) {query_graphql_fragment('HelmFileMetadata')}
+
+ let(:query) do
+ graphql_query_for(:package, { id: package_global_id }, <<~FIELDS)
+ #{all_graphql_fields_for('PackageDetailsType', max_depth: depth, excluded: excluded)}
+ packageFiles {
+ nodes {
+ #{package_files}
+ fileMetadata {
+ #{package_files_metadata}
+ }
+ }
+ }
+ FIELDS
+ end
+
+ subject { post_graphql(query, current_user: user) }
+
+ before do
+ subject
+ end
+
+ it_behaves_like 'a package detail'
+ it_behaves_like 'a package with files'
+
+ it 'has the correct file metadata' do
+ expect(first_file_response_metadata).to include(
+ 'channel' => first_file.helm_file_metadatum.channel
+ )
+ expect(first_file_response_metadata['metadata']).to include(
+ 'name' => first_file.helm_file_metadatum.metadata['name'],
+ 'home' => first_file.helm_file_metadatum.metadata['home'],
+ 'sources' => first_file.helm_file_metadatum.metadata['sources'],
+ 'version' => first_file.helm_file_metadatum.metadata['version'],
+ 'description' => first_file.helm_file_metadatum.metadata['description'],
+ 'keywords' => first_file.helm_file_metadatum.metadata['keywords'],
+ 'maintainers' => first_file.helm_file_metadatum.metadata['maintainers'],
+ 'icon' => first_file.helm_file_metadatum.metadata['icon'],
+ 'apiVersion' => first_file.helm_file_metadatum.metadata['apiVersion'],
+ 'condition' => first_file.helm_file_metadatum.metadata['condition'],
+ 'tags' => first_file.helm_file_metadatum.metadata['tags'],
+ 'appVersion' => first_file.helm_file_metadatum.metadata['appVersion'],
+ 'deprecated' => first_file.helm_file_metadatum.metadata['deprecated'],
+ 'annotations' => first_file.helm_file_metadatum.metadata['annotations'],
+ 'kubeVersion' => first_file.helm_file_metadatum.metadata['kubeVersion'],
+ 'dependencies' => first_file.helm_file_metadatum.metadata['dependencies'],
+ 'type' => first_file.helm_file_metadatum.metadata['type']
+ )
+ end
+end