Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-11 06:10:14 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-11 06:10:14 +0300
commitfb8d6a526f0ef2da9fb247e15f9ff19279dba3d6 (patch)
tree11c6697e314baf4d0e18f0aab10552109633946b
parent9ae44f98c841d785b52087348de2e8cba9a13a2d (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop.yml6
-rw-r--r--app/assets/javascripts/issuable/components/issuable_by_email.vue16
-rw-r--r--app/models/application_setting_implementation.rb1
-rw-r--r--app/views/profiles/personal_access_tokens/index.html.haml16
-rw-r--r--doc/administration/gitaly/praefect.md33
-rw-r--r--doc/development/usage_ping/metrics_instrumentation.md15
-rw-r--r--doc/user/application_security/dast/index.md2
-rw-r--r--doc/user/application_security/sast/index.md2
-rw-r--r--doc/user/application_security/secret_detection/index.md3
-rw-r--r--doc/user/compliance/license_compliance/index.md50
-rw-r--r--lib/generators/gitlab/usage_metric/USAGE9
-rw-r--r--lib/generators/gitlab/usage_metric/templates/instrumentation_class.rb.template14
-rw-r--r--lib/generators/gitlab/usage_metric/templates/instrumentation_class_spec.rb.template7
-rw-r--r--lib/generators/gitlab/usage_metric/usage_metric_generator.rb71
-rw-r--r--locale/gitlab.pot20
-rw-r--r--qa/Gemfile2
-rw-r--r--qa/Gemfile.lock8
-rw-r--r--spec/features/issues/user_resets_their_incoming_email_token_spec.rb2
-rw-r--r--spec/features/profile_spec.rb4
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb11
-rw-r--r--spec/fixtures/lib/generators/gitlab/usage_metric_generator/sample_metric.rb14
-rw-r--r--spec/fixtures/lib/generators/gitlab/usage_metric_generator/sample_metric_test.rb7
-rw-r--r--spec/lib/generators/gitlab/usage_metric_generator_spec.rb70
-rw-r--r--spec/models/application_setting_spec.rb79
-rw-r--r--spec/services/submit_usage_ping_service_spec.rb8
-rw-r--r--tooling/danger/product_intelligence.rb2
26 files changed, 430 insertions, 42 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index e2b85ae8fc9..a26e9ab986b 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -90,6 +90,7 @@ RSpec/FilePath:
- 'spec/frontend/fixtures/*'
- 'ee/spec/frontend/fixtures/*'
- 'spec/requests/api/v3/*'
+ - 'spec/fixtures/**/*'
# Configuration parameters: AllowSubject.
RSpec/MultipleMemoizedHelpers:
@@ -664,3 +665,8 @@ Style/RegexpLiteralMixedPreserve:
- mixed
- mixed_preserve
EnforcedStyle: mixed_preserve
+
+RSpec/TopLevelDescribePath:
+ Exclude:
+ - 'spec/fixtures/**/*.rb'
+ - 'ee/spec/fixtures/**/*.rb'
diff --git a/app/assets/javascripts/issuable/components/issuable_by_email.vue b/app/assets/javascripts/issuable/components/issuable_by_email.vue
index 97807ba1317..c659dfef495 100644
--- a/app/assets/javascripts/issuable/components/issuable_by_email.vue
+++ b/app/assets/javascripts/issuable/components/issuable_by_email.vue
@@ -145,17 +145,23 @@ export default {
<gl-sprintf
:message="
__(
- 'This is a private email address %{helpIcon} generated just for you. Anyone who gets ahold of it can create issues or merge requests as if they were you. You should %{resetLinkStart}reset it%{resetLinkEnd} if that ever happens.',
+ 'This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}.',
)
"
>
<template #helpIcon>
- <gl-link :href="emailsHelpPagePath" target="_blank"
- ><gl-icon class="gl-text-blue-600" name="question-o"
- /></gl-link>
+ <gl-link :href="emailsHelpPagePath" target="_blank">
+ <gl-icon class="gl-text-blue-600" name="question-o" />
+ </gl-link>
</template>
<template #resetLink="{ content }">
- <gl-button variant="link" @click="resetIncomingEmailToken">{{ content }}</gl-button>
+ <gl-button
+ variant="link"
+ data-testid="reset_email_token_link"
+ @click="resetIncomingEmailToken"
+ >
+ {{ content }}
+ </gl-button>
</template>
</gl-sprintf>
</p>
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 5ff1c653f9e..bf9df3b9efc 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -374,6 +374,7 @@ module ApplicationSettingImplementation
def usage_ping_enabled
usage_ping_can_be_configured? && super
end
+ alias_method :usage_ping_enabled?, :usage_ping_enabled
def allowed_key_types
SUPPORTED_KEY_TYPES.select do |type|
diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml
index ee04d9142b1..3661b93e33c 100644
--- a/app/views/profiles/personal_access_tokens/index.html.haml
+++ b/app/views/profiles/personal_access_tokens/index.html.haml
@@ -40,15 +40,15 @@
%h4.gl-mt-0
= s_('AccessTokens|Feed token')
%p
- = s_('AccessTokens|Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.')
+ = s_('AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs.')
%p
= s_('AccessTokens|It cannot be used to access any other data.')
.col-lg-8.feed-token-reset
= label_tag :feed_token, s_('AccessTokens|Feed token'), class: 'label-bold'
= text_field_tag :feed_token, current_user.feed_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true
%p.form-text.text-muted
- - reset_link = link_to s_('AccessTokens|reset it'), [:reset, :feed_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working.') }
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who gets ahold of it can read activity and issue RSS feeds or your calendar feed as if they were you. You should %{link_reset_it} if that ever happens.') % { link_reset_it: reset_link }
+ - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :feed_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working.'), testid: :reset_feed_token_link }
+ - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link }
= reset_message.html_safe
- if incoming_email_token_enabled?
@@ -59,15 +59,15 @@
%h4.gl-mt-0
= s_('AccessTokens|Incoming email token')
%p
- = s_('AccessTokens|Your incoming email token is used to authenticate you when you create a new issue by email, and is included in your personal project-specific email addresses.')
+ = s_('AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses.')
%p
= s_('AccessTokens|It cannot be used to access any other data.')
.col-lg-8.incoming-email-token-reset
= label_tag :incoming_email_token, s_('AccessTokens|Incoming email token'), class: 'label-bold'
= text_field_tag :incoming_email_token, current_user.incoming_email_token, class: 'form-control gl-form-input js-select-on-focus', readonly: true
%p.form-text.text-muted
- - reset_link = link_to s_('AccessTokens|reset it'), [:reset, :incoming_email_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any issue email addresses currently in use will stop working.') }
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who gets ahold of it can create issues as if they were you. You should %{link_reset_it} if that ever happens.') % { link_reset_it: reset_link }
+ - reset_link = link_to s_('AccessTokens|reset this token'), [:reset, :incoming_email_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any issue email addresses currently in use will stop working.'), testid: :reset_email_token_link }
+ - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}.') % { link_reset_it: reset_link }
= reset_message.html_safe
- if static_objects_external_storage_enabled?
@@ -78,7 +78,7 @@
%h4.gl-mt-0
= s_('AccessTokens|Static object token')
%p
- = s_('AccessTokens|Your static object token is used to authenticate you when repository static objects (e.g. archives, blobs, ...) are being served from an external storage.')
+ = s_('AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage.')
%p
= s_('AccessTokens|It cannot be used to access any other data.')
.col-lg-8
@@ -88,5 +88,5 @@
- reset_link = url_for [:reset, :static_object_token, :profile]
- reset_link_start = '<a data-confirm="%{confirm}" rel="nofollow" data-method="put" href="%{url}">'.html_safe % { confirm: s_('AccessTokens|Are you sure?'), url: reset_link }
- reset_link_end = '</a>'.html_safe
- - reset_message = s_('AccessTokens|Keep this token secret. Anyone who gets ahold of it can access repository static objects as if they were you. You should %{reset_link_start}reset it%{reset_link_end} if that ever happens.') % { reset_link_start: reset_link_start, reset_link_end: reset_link_end }
+ - reset_message = s_('AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}.') % { reset_link_start: reset_link_start, reset_link_end: reset_link_end }
= reset_message.html_safe
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index def2ca0d6ef..3b82a492f34 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -1163,15 +1163,36 @@ To migrate existing clusters:
a Praefect node to reattempt it. The migration only runs with `sql` election strategy configured.
1. Running two different election strategies side by side can cause a split brain, where different
- Praefect nodes consider repositories to have different primaries. To avoid this, shut down
- all Praefect nodes before changing the election strategy.
+ Praefect nodes consider repositories to have different primaries. This can be avoided either:
- Do this by running `gitlab-ctl stop praefect` on the Praefect nodes.
+ - If a short downtime is acceptable:
-1. On the Praefect nodes, configure the election strategy in `/etc/gitlab/gitlab.rb` with
- `praefect['failover_election_strategy'] = 'per_repository'`.
+ 1. Shut down all Praefect nodes before changing the election strategy. Do this by running `gitlab-ctl stop praefect` on the Praefect nodes.
-1. Finally, run `gitlab-ctl reconfigure` to reconfigure and restart the Praefect nodes.
+ 1. On the Praefect nodes, configure the election strategy in `/etc/gitlab/gitlab.rb` with `praefect['failover_election_strategy'] = 'per_repository'`.
+
+ 1. Run `gitlab-ctl reconfigure && gitlab-ctl start` to reconfigure and start the Praefects.
+
+ - If downtime is unacceptable:
+
+ 1. Determine which Gitaly node is [the current primary](index.md#determine-primary-gitaly-node).
+
+ 1. Comment out the secondary Gitaly nodes from the virtual storage's configuration in `/etc/gitlab/gitlab.rb`
+ on all Praefect nodes. This ensures there's only one Gitaly node configured, causing both of the election
+ strategies to elect the same Gitaly node as the primary.
+
+ 1. Run `gitlab-ctl reconfigure` on all Praefect nodes. Wait until all Praefect processes have restarted and
+ the old processes have exited. This can take up to one minute.
+
+ 1. On all Praefect nodes, configure the election strategy in `/etc/gitlab/gitlab.rb` with
+ `praefect['failover_election_strategy'] = 'per_repository'`.
+
+ 1. Run `gitlab-ctl reconfigure` on all Praefect nodes. Wait until all of the Praefect processes have restarted and
+ the old processes have exited. This can take up to one minute.
+
+ 1. Uncomment the secondary Gitaly node configuration commented out in the earlier step on all Praefect nodes.
+
+ 1. Run `gitlab-ctl reconfigure` on all Praefect nodes to reconfigure and restart the Praefect processes.
### Deprecated election strategies
diff --git a/doc/development/usage_ping/metrics_instrumentation.md b/doc/development/usage_ping/metrics_instrumentation.md
index e9f6be29454..ff0dbf99a09 100644
--- a/doc/development/usage_ping/metrics_instrumentation.md
+++ b/doc/development/usage_ping/metrics_instrumentation.md
@@ -85,3 +85,18 @@ module Gitlab
end
end
```
+
+## Creating a new metric instrumentation class
+
+To create a stub instrumentation for a Usage Ping metric, you can use a dedicated [generator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/generators/gitlab/usage_metric_generator.rb):
+
+The generator takes the class name as an argument and the following options:
+
+- `--type=TYPE` Required. Indicates the metric type. It must be one of: `database`, `generic`, `redis_hll`.
+- `--ee` Indicates if the metric is for EE.
+
+```shell
+rails generate gitlab:usage_metric CountIssues --type database
+ create lib/gitlab/usage/metrics/instrumentations/count_issues_metric.rb
+ create spec/lib/gitlab/usage/metrics/instrumentations/count_issues_metric_spec.rb
+```
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index fbdef70c7c8..63460763533 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -742,6 +742,8 @@ DAST can be [configured](#customizing-the-dast-settings) using CI/CD variables.
| `DAST_FIRST_SUBMIT_FIELD` | string | The `id` or `name` of the element that when clicked submits the username form of a multi-page login process. [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/9894) in GitLab 12.4. |
| `DAST_ZAP_CLI_OPTIONS` | string | ZAP server command-line options. For example, `-Xmx3072m` would set the Java maximum memory allocation pool size. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
| `DAST_ZAP_LOG_CONFIGURATION` | string | Set to a semicolon-separated list of additional log4j properties for the ZAP Server. For example, `log4j.logger.org.parosproxy.paros.network.HttpSender=DEBUG;log4j.logger.com.crawljax=DEBUG` |
+| `DAST_AGGREGATE_VULNERABILITIES` | boolean | Vulnerability aggregation is set to `true` by default. To disable this feature and see each vulnerability individually set to `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/254043) in GitLab 14.0. |
+| `DAST_MAX_URLS_PER_VULNERABILITY` | number | The maximum number of URLs reported for a single vulnerability. `DAST_MAX_URLS_PER_VULNERABILITY` is set to `50` by default. To list all the URLs set to `0`. [Introduced](https://gitlab.com/gitlab-org/security-products/dast/-/merge_requests/433) in GitLab 13.12. |
| `DAST_AUTH_EXCLUDE_URLS` | URLs | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/289959) in GitLab 13.8, to be removed in 14.0, and replaced by `DAST_EXCLUDE_URLS`. The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. Not supported for API scans. |
1. DAST CI/CD variable available to an on-demand scan.
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index 07b1660da00..ac877fde034 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -490,7 +490,7 @@ Some analyzers can be customized with CI/CD variables.
| `MAVEN_REPO_PATH` | SpotBugs | Path to the Maven local repository (shortcut for the `maven.repo.local` property). |
| `SBT_PATH` | SpotBugs | Path to the `sbt` executable. |
| `FAIL_NEVER` | SpotBugs | Set to `1` to ignore compilation failure. |
-| `SAST_GOSEC_CONFIG` | Gosec | Path to configuration for Gosec (optional). |
+| `SAST_GOSEC_CONFIG` | Gosec | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/328301)** in GitLab 14.0 - use custom rulesets instead. Path to configuration for Gosec (optional). |
| `PHPCS_SECURITY_AUDIT_PHP_EXTENSIONS` | phpcs-security-audit | Comma separated list of additional PHP Extensions. |
| `SAST_DISABLE_BABEL` | NodeJsScan | Disable Babel processing for the NodeJsScan scanner. Set to `true` to disable Babel processing. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33065) in GitLab 13.2.
| `SAST_SEMGREP_METRICS` | Semgrep | Set to `"false"` to disable sending anonymized scan metrics to [r2c](https://r2c.dev/). Default: `true`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/330565) in GitLab 14.0. |
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index b3adfb3ae3c..f4aa9dc2787 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -100,7 +100,8 @@ as shown in the following table:
## Configuration
-> GitLab 13.1 splits Secret Detection from the [SAST configuration](../sast#configuration) into its own CI/CD template. If you're using GitLab 13.0 or earlier and SAST is enabled, then Secret Detection is already enabled.
+> - In GitLab 13.1, Secret Detection was split from the [SAST configuration](../sast#configuration) into its own CI/CD template. If you're using GitLab 13.0 or earlier and SAST is enabled, then Secret Detection is already enabled.
+> - [In GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/297269), Secret Detection jobs `secret_detection_default_branch` and `secret_detection` were consolidated into one job, `secret_detection`.
Secret Detection is performed by a [specific analyzer](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml)
during the `secret-detection` job. It runs regardless of your app's programming language.
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index a509fe0412c..9d6f8216a07 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -109,6 +109,11 @@ include:
The included template creates a `license_scanning` job in your CI/CD pipeline and scans your
dependencies to find their licenses.
+NOTE:
+Before GitLab 12.8, the `license_scanning` job was named `license_management`. GitLab 13.0 removes
+the `license_management` job, so you must migrate to the `license_scanning` job and use the new
+`License-Scanning.gitlab-ci.yml` template.
+
The results are saved as a
[License Compliance report artifact](../../../ci/yaml/README.md#artifactsreportslicense_scanning)
that you can later download and analyze. Due to implementation limitations, we
@@ -553,6 +558,51 @@ For example:
You can supply a custom root certificate to complete TLS verification by using the
`ADDITIONAL_CA_CERT_BUNDLE` [CI/CD variable](#available-cicd-variables).
+### Migration from `license_management` to `license_scanning`
+
+In GitLab 12.8 a new name for `license_management` job was introduced. This change was made to improve clarity around the purpose of the scan, which is to scan and collect the types of licenses present in a projects dependencies.
+GitLab 13.0 drops support for `license_management`.
+If you're using a custom setup for License Compliance, you're required
+to update your CI configuration accordingly:
+
+1. Change the CI template to `License-Scanning.gitlab-ci.yml`.
+1. Change the job name to `license_scanning` (if you mention it in `.gitlab-ci.yml`).
+1. Change the artifact name to `license_scanning`, and the filename to `gl-license-scanning-report.json` (if you mention it in `.gitlab-ci.yml`).
+
+For example, the following `.gitlab-ci.yml`:
+
+```yaml
+include:
+ - template: License-Management.gitlab-ci.yml
+
+license_management:
+ artifacts:
+ reports:
+ license_management: gl-license-management-report.json
+```
+
+Should be changed to:
+
+```yaml
+include:
+ - template: Security/License-Scanning.gitlab-ci.yml
+
+license_scanning:
+ artifacts:
+ reports:
+ license_scanning: gl-license-scanning-report.json
+```
+
+If you use the `license_management` artifact in GitLab 13.0 or later, the License Compliance job generates this error:
+
+```plaintext
+WARNING: Uploading artifacts to coordinator... failed id=:id responseStatus=400 Bad Request status=400 Bad Request token=:sha
+
+FATAL: invalid_argument
+```
+
+If you encounter this error, follow the instructions described in this section.
+
## Running License Compliance in an offline environment
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
diff --git a/lib/generators/gitlab/usage_metric/USAGE b/lib/generators/gitlab/usage_metric/USAGE
new file mode 100644
index 00000000000..3a2166c3bb1
--- /dev/null
+++ b/lib/generators/gitlab/usage_metric/USAGE
@@ -0,0 +1,9 @@
+Description:
+ Creates a stub instrumentation for a Service Ping metric
+
+Example:
+ rails generate gitlab:usage_metric CountIssues --type database
+
+ This will create:
+ lib/gitlab/usage/metrics/instrumentations/count_issues_metric.rb
+ spec/lib/gitlab/usage/metrics/instrumentations/count_issues_metric_spec.rb
diff --git a/lib/generators/gitlab/usage_metric/templates/instrumentation_class.rb.template b/lib/generators/gitlab/usage_metric/templates/instrumentation_class.rb.template
new file mode 100644
index 00000000000..603b6f3bc8a
--- /dev/null
+++ b/lib/generators/gitlab/usage_metric/templates/instrumentation_class.rb.template
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class <%= class_name %>Metric < <%= metric_superclass %>Metric
+ def value
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/generators/gitlab/usage_metric/templates/instrumentation_class_spec.rb.template b/lib/generators/gitlab/usage_metric/templates/instrumentation_class_spec.rb.template
new file mode 100644
index 00000000000..e984daee0a4
--- /dev/null
+++ b/lib/generators/gitlab/usage_metric/templates/instrumentation_class_spec.rb.template
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::Metrics::Instrumentations::<%= class_name %>Metric do
+ it_behaves_like 'a correct instrumented metric value', {}, 1
+end
diff --git a/lib/generators/gitlab/usage_metric/usage_metric_generator.rb b/lib/generators/gitlab/usage_metric/usage_metric_generator.rb
new file mode 100644
index 00000000000..f7125fdc911
--- /dev/null
+++ b/lib/generators/gitlab/usage_metric/usage_metric_generator.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'rails/generators'
+
+module Gitlab
+ class UsageMetricGenerator < Rails::Generators::Base
+ CE_DIR = 'lib/gitlab/usage/metrics/instrumentations'
+ EE_DIR = 'ee/lib/ee/gitlab/usage/metrics/instrumentations'
+ SPEC_CE_DIR = 'spec/lib/gitlab/usage/metrics/instrumentations'
+ SPEC_EE_DIR = 'ee/spec/lib/ee/gitlab/usage/metrics/instrumentations'
+
+ ALLOWED_SUPERCLASSES = {
+ generic: 'Generic',
+ database: 'Database',
+ redis_hll: 'RedisHLL'
+ }.freeze
+
+ source_root File.expand_path('templates', __dir__)
+
+ class_option :ee, type: :boolean, optional: true, default: false, desc: 'Indicates if instrumentation is for EE'
+ class_option :type, type: :string, desc: "Metric type, must be one of: #{ALLOWED_SUPERCLASSES.keys.join(', ')}"
+
+ argument :class_name, type: :string, desc: 'Instrumentation class name, e.g.: CountIssues'
+
+ def create_class_files
+ validate!
+
+ template "instrumentation_class.rb.template", file_path
+ template "instrumentation_class_spec.rb.template", spec_file_path
+ end
+
+ private
+
+ def validate!
+ raise ArgumentError, "Type is required, valid options are #{ALLOWED_SUPERCLASSES.keys.join(', ')}" unless type.present?
+ raise ArgumentError, "Unknown type '#{type}', valid options are #{ALLOWED_SUPERCLASSES.keys.join(', ')}" if metric_superclass.nil?
+ end
+
+ def ee?
+ options[:ee]
+ end
+
+ def type
+ options[:type]
+ end
+
+ def file_path
+ dir = ee? ? EE_DIR : CE_DIR
+
+ File.join(dir, file_name)
+ end
+
+ def spec_file_path
+ dir = ee? ? SPEC_EE_DIR : SPEC_CE_DIR
+
+ File.join(dir, spec_file_name)
+ end
+
+ def file_name
+ "#{class_name.underscore}_metric.rb"
+ end
+
+ def spec_file_name
+ "#{class_name.underscore}_metric_spec.rb"
+ end
+
+ def metric_superclass
+ ALLOWED_SUPERCLASSES[type.to_sym]
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 540d738b2a8..d6f791b64ea 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1744,13 +1744,13 @@ msgstr ""
msgid "AccessTokens|It cannot be used to access any other data."
msgstr ""
-msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can access repository static objects as if they were you. You should %{reset_link_start}reset it%{reset_link_end} if that ever happens."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{reset_link_start}reset this token%{reset_link_end}."
msgstr ""
-msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can create issues as if they were you. You should %{link_reset_it} if that ever happens."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{link_reset_it}."
msgstr ""
-msgid "AccessTokens|Keep this token secret. Anyone who gets ahold of it can read activity and issue RSS feeds or your calendar feed as if they were you. You should %{link_reset_it} if that ever happens."
+msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{link_reset_it}."
msgstr ""
msgid "AccessTokens|Personal Access Tokens"
@@ -1768,16 +1768,16 @@ msgstr ""
msgid "AccessTokens|You can generate a personal access token for each application you use that needs access to the GitLab API."
msgstr ""
-msgid "AccessTokens|Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs."
+msgid "AccessTokens|Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
msgstr ""
-msgid "AccessTokens|Your incoming email token is used to authenticate you when you create a new issue by email, and is included in your personal project-specific email addresses."
+msgid "AccessTokens|Your incoming email token authenticates you when you create a new issue by email, and is included in your personal project-specific email addresses."
msgstr ""
-msgid "AccessTokens|Your static object token is used to authenticate you when repository static objects (e.g. archives, blobs, ...) are being served from an external storage."
+msgid "AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage."
msgstr ""
-msgid "AccessTokens|reset it"
+msgid "AccessTokens|reset this token"
msgstr ""
msgid "AccessibilityReport|Learn more"
@@ -28925,7 +28925,7 @@ msgstr ""
msgid "SecurityReports|Add projects"
msgstr ""
-msgid "SecurityReports|All"
+msgid "SecurityReports|All activity"
msgstr ""
msgid "SecurityReports|Although it's rare to have no vulnerabilities, it can happen. Check your settings to make sure you've set up your dashboard correctly."
@@ -33255,7 +33255,7 @@ msgstr ""
msgid "This is a merge train pipeline"
msgstr ""
-msgid "This is a private email address %{helpIcon} generated just for you. Anyone who gets ahold of it can create issues or merge requests as if they were you. You should %{resetLinkStart}reset it%{resetLinkEnd} if that ever happens."
+msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
msgid "This is a security log of important events involving your account."
@@ -36172,7 +36172,7 @@ msgstr ""
msgid "VulnerabilityManagement|invalid issue link or ID"
msgstr ""
-msgid "VulnerabilityStatusTypes|All"
+msgid "VulnerabilityStatusTypes|All statuses"
msgstr ""
msgid "VulnerabilityStatusTypes|Confirmed"
diff --git a/qa/Gemfile b/qa/Gemfile
index 58cadb1a97c..0cb53ca99dc 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -4,7 +4,7 @@ source 'https://rubygems.org'
gem 'gitlab-qa'
gem 'activesupport', '~> 6.1.3.2' # This should stay in sync with the root's Gemfile
-gem 'allure-rspec', '~> 2.13.10'
+gem 'allure-rspec', '~> 2.14.1'
gem 'capybara', '~> 3.29.0'
gem 'capybara-screenshot', '~> 1.0.23'
gem 'rake', '~> 12.3.3'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 7b79c961e5f..8b6c4ca0d3e 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -19,10 +19,10 @@ GEM
rack-test (>= 1.1.0, < 2.0)
rest-client (>= 2.0.2, < 3.0)
rspec (~> 3.8)
- allure-rspec (2.13.10)
- allure-ruby-commons (= 2.13.10)
+ allure-rspec (2.14.1)
+ allure-ruby-commons (= 2.14.1)
rspec-core (>= 3.8, < 4)
- allure-ruby-commons (2.13.10)
+ allure-ruby-commons (2.14.1)
mime-types (>= 3.3, < 4)
oj (>= 3.10, < 4)
require_all (>= 2, < 4)
@@ -197,7 +197,7 @@ PLATFORMS
DEPENDENCIES
activesupport (~> 6.1.3.2)
airborne (~> 0.3.4)
- allure-rspec (~> 2.13.10)
+ allure-rspec (~> 2.14.1)
capybara (~> 3.29.0)
capybara-screenshot (~> 1.0.23)
chemlab (~> 0.5)
diff --git a/spec/features/issues/user_resets_their_incoming_email_token_spec.rb b/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
index 9e47639d80f..4580378dc8a 100644
--- a/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
+++ b/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'Issues > User resets their incoming email token' do
page.within '#issuable-email-modal' do
previous_token = page.find('input[type="text"]').value
- click_button 'reset it'
+ find('[data-testid="reset_email_token_link"]').click
wait_for_requests
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 84ea9495f08..0f453f1c1e5 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -70,7 +70,7 @@ RSpec.describe 'Profile account page', :js do
within('.feed-token-reset') do
previous_token = find("#feed_token").value
- accept_confirm { click_link('reset it') }
+ accept_confirm { find('[data-testid="reset_feed_token_link"]').click }
expect(find('#feed_token').value).not_to eq(previous_token)
end
@@ -89,7 +89,7 @@ RSpec.describe 'Profile account page', :js do
within('.incoming-email-token-reset') do
previous_token = find('#incoming_email_token').value
- accept_confirm { click_link('reset it') }
+ accept_confirm { find('[data-testid="reset_email_token_link"]').click }
expect(find('#incoming_email_token').value).not_to eq(previous_token)
end
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index c85657c89d5..379c25d6002 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -22,6 +22,10 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
find("#feed_token").value
end
+ def feed_token_description
+ "Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
+ end
+
def disallow_personal_access_token_saves!
allow(PersonalAccessTokens::CreateService).to receive(:new).and_return(pat_create_service)
@@ -123,8 +127,9 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false)
visit profile_personal_access_tokens_path
- expect(page).to have_content("Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.")
expect(feed_token).to eq(user.feed_token)
+
+ expect(page).to have_content(feed_token_description)
end
end
@@ -133,8 +138,8 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(true)
visit profile_personal_access_tokens_path
- expect(page).not_to have_content("Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.")
- expect(page).not_to have_css("#feed_token")
+ expect(page).to have_no_content(feed_token_description)
+ expect(page).to have_no_css("#feed_token")
end
end
end
diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_generator/sample_metric.rb b/spec/fixtures/lib/generators/gitlab/usage_metric_generator/sample_metric.rb
new file mode 100644
index 00000000000..9816ff7c9eb
--- /dev/null
+++ b/spec/fixtures/lib/generators/gitlab/usage_metric_generator/sample_metric.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class CountFooMetric < RedisHLLMetric
+ def value
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_generator/sample_metric_test.rb b/spec/fixtures/lib/generators/gitlab/usage_metric_generator/sample_metric_test.rb
new file mode 100644
index 00000000000..bc7df779a58
--- /dev/null
+++ b/spec/fixtures/lib/generators/gitlab/usage_metric_generator/sample_metric_test.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountFooMetric do
+ it_behaves_like 'a correct instrumented metric value', {}, 1
+end
diff --git a/spec/lib/generators/gitlab/usage_metric_generator_spec.rb b/spec/lib/generators/gitlab/usage_metric_generator_spec.rb
new file mode 100644
index 00000000000..f38815acca6
--- /dev/null
+++ b/spec/lib/generators/gitlab/usage_metric_generator_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::UsageMetricGenerator, :silence_stdout do
+ let(:ce_temp_dir) { Dir.mktmpdir }
+ let(:ee_temp_dir) { Dir.mktmpdir }
+ let(:spec_ce_temp_dir) { Dir.mktmpdir }
+ let(:spec_ee_temp_dir) { Dir.mktmpdir }
+ let(:args) { ['CountFoo'] }
+ let(:options) { { 'type' => 'redis_hll' } }
+
+ before do
+ stub_const("#{described_class}::CE_DIR", ce_temp_dir)
+ stub_const("#{described_class}::EE_DIR", ee_temp_dir)
+ stub_const("#{described_class}::SPEC_CE_DIR", spec_ce_temp_dir)
+ stub_const("#{described_class}::SPEC_EE_DIR", spec_ee_temp_dir)
+ end
+
+ after do
+ FileUtils.rm_rf([ce_temp_dir, ee_temp_dir, spec_ce_temp_dir, spec_ee_temp_dir])
+ end
+
+ def expect_generated_file(directory, file_name, content)
+ file_path = File.join(directory, file_name)
+ file = File.read(file_path)
+
+ expect(file).to eq(content)
+ end
+
+ describe 'Creating metric instrumentation files' do
+ let(:sample_metric_dir) { 'lib/generators/gitlab/usage_metric_generator' }
+ let(:sample_metric) { fixture_file(File.join(sample_metric_dir, 'sample_metric.rb')) }
+ let(:sample_spec) { fixture_file(File.join(sample_metric_dir, 'sample_metric_test.rb')) }
+
+ it 'creates CE metric instrumentation files using the template' do
+ described_class.new(args, options).invoke_all
+
+ expect_generated_file(ce_temp_dir, 'count_foo_metric.rb', sample_metric)
+ expect_generated_file(spec_ce_temp_dir, 'count_foo_metric_spec.rb', sample_spec)
+ end
+
+ context 'with EE flag true' do
+ let(:options) { { 'type' => 'redis_hll', 'ee' => true } }
+
+ it 'creates EE metric instrumentation files using the template' do
+ described_class.new(args, options).invoke_all
+
+ expect_generated_file(ee_temp_dir, 'count_foo_metric.rb', sample_metric)
+ expect_generated_file(spec_ee_temp_dir, 'count_foo_metric_spec.rb', sample_spec)
+ end
+ end
+
+ context 'with type option missing' do
+ let(:options) { {} }
+
+ it 'raises an ArgumentError' do
+ expect { described_class.new(args, options).invoke_all }.to raise_error(ArgumentError, /Type is required/)
+ end
+ end
+
+ context 'with type option value not included in approved superclasses' do
+ let(:options) { { 'type' => 'some_other_type' } }
+
+ it 'raises an ArgumentError' do
+ expect { described_class.new(args, options).invoke_all }.to raise_error(ArgumentError, /Unknown type 'some_other_type'/)
+ end
+ end
+ end
+end
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 4b4e7820f7a..c13d83d1685 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -363,6 +363,85 @@ RSpec.describe ApplicationSetting do
.is_less_than(65536)
end
+ describe 'usage_ping_enabled setting' do
+ shared_examples 'usage ping enabled' do
+ it do
+ expect(setting.usage_ping_enabled).to eq(true)
+ expect(setting.usage_ping_enabled?).to eq(true)
+ end
+ end
+
+ shared_examples 'usage ping disabled' do
+ it do
+ expect(setting.usage_ping_enabled).to eq(false)
+ expect(setting.usage_ping_enabled?).to eq(false)
+ end
+ end
+
+ context 'when setting is in database' do
+ context 'with usage_ping_enabled disabled' do
+ before do
+ setting.update!(usage_ping_enabled: false)
+ end
+
+ it_behaves_like 'usage ping disabled'
+ end
+
+ context 'with usage_ping_enabled enabled' do
+ before do
+ setting.update!(usage_ping_enabled: true)
+ end
+
+ it_behaves_like 'usage ping enabled'
+ end
+ end
+
+ context 'when setting is in GitLab config' do
+ context 'with usage_ping_enabled disabled' do
+ before do
+ allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(false)
+ end
+
+ it_behaves_like 'usage ping disabled'
+ end
+
+ context 'with usage_ping_enabled enabled' do
+ before do
+ allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(true)
+ end
+
+ it_behaves_like 'usage ping enabled'
+ end
+ end
+
+ context 'when setting in database false and setting in GitLab config true' do
+ before do
+ setting.update!(usage_ping_enabled: false)
+ allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(true)
+ end
+
+ it_behaves_like 'usage ping disabled'
+ end
+
+ context 'when setting database true and setting in GitLab config false' do
+ before do
+ setting.update!(usage_ping_enabled: true)
+ allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(false)
+ end
+
+ it_behaves_like 'usage ping disabled'
+ end
+
+ context 'when setting database true and setting in GitLab config true' do
+ before do
+ setting.update!(usage_ping_enabled: true)
+ allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(true)
+ end
+
+ it_behaves_like 'usage ping enabled'
+ end
+ end
+
context 'key restrictions' do
it 'supports all key types' do
expect(described_class::SUPPORTED_KEY_TYPES).to contain_exactly(:rsa, :dsa, :ecdsa, :ed25519)
diff --git a/spec/services/submit_usage_ping_service_spec.rb b/spec/services/submit_usage_ping_service_spec.rb
index a9f1b2c2b2d..7133dc35fc3 100644
--- a/spec/services/submit_usage_ping_service_spec.rb
+++ b/spec/services/submit_usage_ping_service_spec.rb
@@ -90,6 +90,14 @@ RSpec.describe SubmitUsagePingService do
it_behaves_like 'does not run'
end
+ context 'when usage ping is disabled from GitLab config file' do
+ before do
+ stub_config_setting(usage_ping_enabled: false)
+ end
+
+ it_behaves_like 'does not run'
+ end
+
context 'when usage ping is enabled' do
before do
stub_usage_data_connections
diff --git a/tooling/danger/product_intelligence.rb b/tooling/danger/product_intelligence.rb
index e05557b58dd..0f77f6c6a71 100644
--- a/tooling/danger/product_intelligence.rb
+++ b/tooling/danger/product_intelligence.rb
@@ -17,8 +17,10 @@ module Tooling
'app/assets/javascripts/tracking.js',
'spec/frontend/tracking_spec.js',
'generator_templates/usage_metric_definition/metric_definition.yml',
+ 'lib/generators/gitlab/usage_metric/usage_metric_generator.rb',
'lib/generators/gitlab/usage_metric_definition_generator.rb',
'lib/generators/gitlab/usage_metric_definition/redis_hll_generator.rb',
+ 'spec/lib/generators/gitlab/usage_metric_generator_spec.rb',
'spec/lib/generators/gitlab/usage_metric_definition_generator_spec.rb',
'spec/lib/generators/gitlab/usage_metric_definition/redis_hll_generator_spec.rb',
'config/metrics/schema.json'