Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-07-08 12:08:30 +00:00
parent 7752bfa10f
commit dd18ae74af
39 changed files with 289 additions and 81 deletions

View file

@ -1,10 +1,12 @@
<script>
import { GlAlert } from '@gitlab/ui';
import { EditorContent as TiptapEditorContent } from '@tiptap/vue-2';
import { ContentEditor } from '../services/content_editor';
import TopToolbar from './top_toolbar.vue';
export default {
components: {
GlAlert,
TiptapEditorContent,
TopToolbar,
},
@ -14,15 +16,30 @@ export default {
required: true,
},
},
data() {
return {
error: '',
};
},
mounted() {
this.contentEditor.tiptapEditor.on('error', (error) => {
this.error = error;
});
},
};
</script>
<template>
<div
data-testid="content-editor"
class="md-area"
:class="{ 'is-focused': contentEditor.tiptapEditor.isFocused }"
>
<top-toolbar class="gl-mb-4" :content-editor="contentEditor" />
<tiptap-editor-content class="md" :editor="contentEditor.tiptapEditor" />
<div>
<gl-alert v-if="error" class="gl-mb-6" variant="danger" @dismiss="error = ''">
{{ error }}
</gl-alert>
<div
data-testid="content-editor"
class="md-area"
:class="{ 'is-focused': contentEditor.tiptapEditor.isFocused }"
>
<top-toolbar ref="toolbar" class="gl-mb-4" :content-editor="contentEditor" />
<tiptap-editor-content class="md" :editor="contentEditor.tiptapEditor" />
</div>
</div>
</template>

View file

@ -1,3 +1,4 @@
import IssueStatusIcon from '~/reports/components/issue_status_icon.vue';
import AccessibilityIssueBody from '../accessibility_report/components/accessibility_issue_body.vue';
import CodequalityIssueBody from '../codequality_report/components/codequality_issue_body.vue';
import TestIssueBody from '../grouped_test_report/components/test_issue_body.vue';
@ -13,3 +14,11 @@ export const componentNames = {
CodequalityIssueBody: CodequalityIssueBody.name,
TestIssueBody: TestIssueBody.name,
};
export const iconComponents = {
IssueStatusIcon,
};
export const iconComponentNames = {
IssueStatusIcon: IssueStatusIcon.name,
};

View file

@ -1,12 +1,16 @@
<script>
import { components, componentNames } from 'ee_else_ce/reports/components/issue_body';
import IssueStatusIcon from '~/reports/components/issue_status_icon.vue';
import {
components,
componentNames,
iconComponents,
iconComponentNames,
} from 'ee_else_ce/reports/components/issue_body';
export default {
name: 'ReportItem',
components: {
IssueStatusIcon,
...components,
...iconComponents,
},
props: {
issue: {
@ -19,6 +23,12 @@ export default {
default: '',
validator: (value) => value === '' || Object.values(componentNames).includes(value),
},
iconComponent: {
type: String,
required: false,
default: iconComponentNames.IssueStatusIcon,
validator: (value) => Object.values(iconComponentNames).includes(value),
},
// failed || success
status: {
type: String,
@ -48,11 +58,12 @@ export default {
class="report-block-list-issue align-items-center"
data-qa-selector="report_item_row"
>
<issue-status-icon
<component
:is="iconComponent"
v-if="showReportSectionStatusIcon"
:status="status"
:status-icon-size="statusIconSize"
class="gl-mr-3"
class="gl-mr-2"
/>
<component :is="component" v-if="component" :issue="issue" :status="status" :is-new="isNew" />

View file

@ -15,6 +15,20 @@ class Admin::BackgroundMigrationsController < Admin::ApplicationController
@successful_rows_counts = batched_migration_class.successful_rows_counts(@migrations.map(&:id))
end
def pause
migration = batched_migration_class.find(params[:id])
migration.paused!
redirect_back fallback_location: { action: 'index' }
end
def resume
migration = batched_migration_class.find(params[:id])
migration.active!
redirect_back fallback_location: { action: 'index' }
end
private
def batched_migration_class

View file

@ -87,7 +87,7 @@ class Import::BulkImportsController < ApplicationController
def client
@client ||= BulkImports::Clients::HTTP.new(
uri: session[url_key],
url: session[url_key],
token: session[access_token_key],
per_page: params[:per_page],
page: params[:page]

View file

@ -9,7 +9,7 @@ module BulkImports
@relation = relation
@entity = @pipeline_tracker.entity
@configuration = @entity.bulk_import.configuration
@client = Clients::HTTP.new(uri: @configuration.url, token: @configuration.access_token)
@client = Clients::HTTP.new(url: @configuration.url, token: @configuration.access_token)
end
def started?

View file

@ -434,6 +434,7 @@ class User < ApplicationRecord
scope :by_id_and_login, ->(id, login) { where(id: id).where('username = LOWER(:login) OR email = LOWER(:login)', login: login) }
scope :dormant, -> { active.where('last_activity_on <= ?', MINIMUM_INACTIVE_DAYS.day.ago.to_date) }
scope :with_no_activity, -> { active.where(last_activity_on: nil) }
scope :by_provider_and_extern_uid, ->(provider, extern_uid) { joins(:identities).merge(Identity.with_extern_uid(provider, extern_uid)) }
def preferred_language
read_attribute('preferred_language') ||
@ -558,10 +559,6 @@ class User < ApplicationRecord
end
end
def for_github_id(id)
joins(:identities).merge(Identity.with_extern_uid(:github, id))
end
# Find a User by their primary email or any associated secondary email
def find_by_any_email(email, confirmed: false)
return unless email

View file

@ -55,7 +55,7 @@ module BulkImports
def http_client
@http_client ||= BulkImports::Clients::HTTP.new(
uri: configuration.url,
url: configuration.url,
token: configuration.access_token
)
end

View file

@ -8,3 +8,12 @@
= _('Unknown')
%td{ role: 'cell', data: { label: _('Status') } }
%span.badge.badge-pill.gl-badge.sm{ class: batched_migration_status_badge_class_name(migration) }= migration.status.humanize
%td{ role: 'cell', data: { label: _('Action') } }
- if migration.active?
= button_to pause_admin_background_migration_path(migration),
class: 'gl-button btn btn-icon has-tooltip', title: _('Pause'), 'aria-label' => _('Pause') do
= sprite_icon('pause', css_class: 'gl-button-icon gl-icon')
- elsif migration.paused?
= button_to resume_admin_background_migration_path(migration),
class: 'gl-button btn btn-icon has-tooltip', title: _('Resume'), 'aria-label' => _('Resume') do
= sprite_icon('play', css_class: 'gl-button-icon gl-icon')

View file

@ -29,6 +29,7 @@
%th.table-th-transparent.border-bottom{ role: 'cell' }= _('Migration')
%th.table-th-transparent.border-bottom{ role: 'cell' }= _('Progress')
%th.table-th-transparent.border-bottom{ role: 'cell' }= _('Status')
%th.table-th-transparent.border-bottom{ role: 'cell' }
%tbody{ role: 'rowgroup' }
= render partial: 'migration', collection: @migrations

View file

@ -25,7 +25,7 @@ module BulkImports
def http_client(configuration)
@client ||= Clients::HTTP.new(
uri: configuration.url,
url: configuration.url,
token: configuration.access_token
)
end

View file

@ -89,7 +89,13 @@ namespace :admin do
get :instance_review, to: 'instance_review#index'
resources :background_migrations, only: [:index]
resources :background_migrations, only: [:index] do
member do
post :pause
post :resume
end
end
resource :health_check, controller: 'health_check', only: [:show]
resource :background_jobs, controller: 'background_jobs', only: [:show]

View file

@ -170,7 +170,7 @@ The following API resources are available outside of project and group contexts
| [Suggestions](suggestions.md) | `/suggestions` |
| [System hooks](system_hooks.md) | `/hooks` |
| [To-dos](todos.md) | `/todos` |
| [Usage data](usage_data.md) | `/usage_data` (For GitLab instance [Administrator](../user/permissions.md) users only) |
| [Service Data](usage_data.md) | `/usage_data` (For GitLab instance [Administrator](../user/permissions.md) users only) |
| [Users](users.md) | `/users` |
| [Validate `.gitlab-ci.yml` file](lint.md) | `/lint` |
| [Version](version.md) | `/version` |

View file

@ -5,9 +5,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference, api
---
# Usage Data API **(FREE SELF)**
# Service Data API **(FREE SELF)**
The Usage Data API is associated with [Service Ping](../development/usage_ping/index.md).
The Service Data API is associated with [Service Ping](../development/usage_ping/index.md).
## Export metric definitions as a single YAML file

View file

@ -25,7 +25,7 @@ A database review is required for:
generally up to the author of a merge request to decide whether or
not complex queries are being introduced and if they require a
database review.
- Changes in usage data metrics that use `count`, `distinct_count` and `estimate_batch_distinct_count`.
- Changes in Service Data metrics that use `count`, `distinct_count` and `estimate_batch_distinct_count`.
These metrics could have complex queries over large tables.
See the [Product Intelligence Guide](https://about.gitlab.com/handbook/product/product-intelligence-guide/)
for implementation details.
@ -118,6 +118,7 @@ test its execution using `CREATE INDEX CONCURRENTLY` in the `#database-lab` Slac
Keep in mind that in this case you may need to split the migration and the application changes in separate releases to ensure the index
will be in place when the code that needs it will be deployed.
- Trigger the [database testing](../architecture/blueprints/database_testing/index.md) job (`db:gitlabcom-database-testing`) in the `test` stage.
- This job runs migrations in a production-like environment (similar to `#database_lab`) and posts to the MR its findings (queries, runtime, size change).
- Review migration runtimes and any warnings.
#### Preparation when adding or modifying queries

View file

@ -46,7 +46,7 @@ and can show your instance's usage statistics to your users.
We use the following terminology to describe the Service Ping components:
- **Service Ping**: the process that collects and generates a JSON payload.
- **Usage data**: the contents of the Service Ping JSON payload. This includes metrics.
- **Service Data**: the contents of the Service Ping JSON payload. This includes metrics.
- **Metrics**: primarily made up of row counts for different tables in an instance's database. Each
metric has a corresponding [metric definition](metrics_dictionary.md#metrics-definition-and-validation)
in a YAML file.
@ -882,9 +882,9 @@ We can also disable tracking completely by using the global flag:
/chatops run feature set redis_hll_tracking false
```
##### Known events are added automatically in usage data payload
##### Known events are added automatically in Service Data payload
All events added in [`known_events/common.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/common.yml) are automatically added to usage data generation under the `redis_hll_counters` key. This column is stored in [version-app as a JSON](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L209).
All events added in [`known_events/common.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/common.yml) are automatically added to Service Data generation under the `redis_hll_counters` key. This column is stored in [version-app as a JSON](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L209).
For each event we add metrics for the weekly and monthly time frames, and totals for each where applicable:
- `#{event_name}_weekly`: Data for 7 days for daily [aggregation](#adding-new-events) events and data for the last complete week for weekly [aggregation](#adding-new-events) events.
@ -960,7 +960,7 @@ alt_usage_data(999)
### Adding counters to build new metrics
When adding the results of two counters, use the `add` usage data method that
When adding the results of two counters, use the `add` Service Data method that
handles fallback values and exceptions. It also generates a valid [SQL export](#exporting-service-ping-sql-queries-and-definitions).
Example usage:
@ -973,7 +973,7 @@ add(User.active, User.bot)
In those cases where operational metrics should be part of Service Ping, a database or Redis query is unlikely
to provide useful data. Instead, Prometheus might be more appropriate, because most GitLab architectural
components publish metrics to it that can be queried back, aggregated, and included as usage data.
components publish metrics to it that can be queried back, aggregated, and included as Service Data.
NOTE:
Prometheus as a data source for Service Ping is currently only available for single-node Omnibus installations
@ -1074,7 +1074,7 @@ When adding, updating, or removing metrics, please update the [Metrics Dictionar
### 6. Add new metric to Versions Application
Check if new metrics need to be added to the Versions Application. See `usage_data` [schema](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L147) and usage data [parameters accepted](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/app/services/usage_ping.rb). Any metrics added under the `counts` key are saved in the `stats` column.
Check if new metrics need to be added to the Versions Application. See `usage_data` [schema](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L147) and Service Data [parameters accepted](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/app/services/usage_ping.rb). Any metrics added under the `counts` key are saved in the `stats` column.
### 7. Add the feature label
@ -1288,7 +1288,7 @@ To declare the aggregate of events collected with [Redis HLL Counters](#redis-hl
you must fulfill the following requirements:
1. All events listed at `events` attribute must come from
[`known_events/*.yml`](#known-events-are-added-automatically-in-usage-data-payload) files.
[`known_events/*.yml`](#known-events-are-added-automatically-in-service-data-payload) files.
1. All events listed at `events` attribute must have the same `redis_slot` attribute.
1. All events listed at `events` attribute must have the same `aggregation` attribute.
1. `time_frame` does not include `all` value, which is unavailable for Redis sourced aggregated metrics.

View file

@ -216,7 +216,7 @@ create ee/config/metrics/counts_7d/issues.yml
## Metrics added dynamic to Service Ping payload
The [Redis HLL metrics](index.md#known-events-are-added-automatically-in-usage-data-payload) are added automatically to Service Ping payload.
The [Redis HLL metrics](index.md#known-events-are-added-automatically-in-service-data-payload) are added automatically to Service Ping payload.
A YAML metric definition is required for each metric. A dedicated generator is provided to create metric definitions for Redis HLL events.

View file

@ -15,7 +15,7 @@ This guide describes how to develop Service Ping metrics using metrics instrumen
- Implements the logic that calculates the value for a Service Ping metric.
- **Metric definition**
The Usage Data metric YAML definition.
The Service Data metric YAML definition.
- **Hardening**:
Hardening a method is the process that ensures the method fails safe, returning a fallback value like -1.

View file

@ -46,7 +46,7 @@ The following Rake tasks are available for use with GitLab:
| [Repository storage](../administration/raketasks/storage.md) | List and migrate existing projects and attachments from legacy storage to hashed storage. |
| [Uploads migrate](../administration/raketasks/uploads/migrate.md) | Migrate uploads between local storage and object storage. |
| [Uploads sanitize](../administration/raketasks/uploads/sanitize.md) | Remove EXIF data from images uploaded to earlier versions of GitLab. |
| [Usage data](../administration/troubleshooting/gitlab_rails_cheat_sheet.md#generate-service-ping) | Generate and troubleshoot [Service Ping](../development/usage_ping/index.md). |
| [Service Data](../administration/troubleshooting/gitlab_rails_cheat_sheet.md#generate-service-ping) | Generate and troubleshoot [Service Ping](../development/usage_ping/index.md). |
| [User management](user_management.md) | Perform user management tasks. |
| [Webhooks administration](web_hooks.md) | Maintain project webhooks. |
| [X.509 signatures](x509_signatures.md) | Update X.509 commit signatures, which can be useful if the certificate store changed. |

View file

@ -86,7 +86,7 @@ To access the default page for Admin Area settings:
| [Metrics - Grafana](../../../administration/monitoring/performance/grafana_configuration.md#integration-with-gitlab-ui) | Enable and configure Grafana. |
| [Profiling - Performance bar](../../../administration/monitoring/performance/performance_bar.md#enable-the-performance-bar-via-the-admin-area) | Enable access to the Performance Bar for a given group. |
| [Self monitoring](../../../administration/monitoring/gitlab_self_monitoring_project/index.md#creating-the-self-monitoring-project) | Enable or disable instance self monitoring. |
| [Usage statistics](usage_statistics.md) | Enable or disable version check and usage ping. |
| [Usage statistics](usage_statistics.md) | Enable or disable version check and Service Ping. |
| [Pseudonymizer data collection](../../../administration/pseudonymizer.md) **(ULTIMATE)** | Enable or disable the Pseudonymizer data collection. |
## Network

View file

@ -16,8 +16,8 @@ tasks in a secure and cloud-native way. It enables:
- Integrating GitLab with a Kubernetes cluster behind a firewall or NAT
(network address translation).
- Pull-based GitOps deployments by leveraging the
[GitOps Engine](https://github.com/argoproj/gitops-engine).
- Pull-based GitOps deployments.
- [Inventory object](../../infrastructure/clusters/deploy/inventory_object.md) to keep track of objects applied to your cluster.
- Real-time access to API endpoints in a cluster.
- Alert generation based on [Container network policy](../../application_security/threat_monitoring/index.md#container-network-policy).
- [CI/CD Tunnel](ci_cd_tunnel.md) that enables users to access Kubernetes clusters from GitLab CI/CD jobs even if there is no network connectivity between GitLab Runner and a cluster.
@ -38,7 +38,9 @@ sequenceDiagram
participant M as Manifest repository
participant K as Kubernetes Agent
participant C as Agent configuration repository
K->C: Grab the configuration
loop Regularly
K-->>C: Grab the configuration
end
D->>+A: Pushing code changes
A->>M: Updating manifest
loop Regularly

View file

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.7.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in GitLab 13.11, the Kubernetes Agent became available on GitLab.com.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0, the `resource_inclusions` and `resource_exclusions` attributes were removed.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0, the `resource_inclusions` and `resource_exclusions` attributes were removed and `reconcile_timeout`, `dry_run_strategy`, `prune`, `prune_timeout`, `prune_propagation_policy`, and `inventory_policy` attributes were added.
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
@ -51,6 +51,7 @@ gitops:
# in YAML or JSON format.
- id: gitlab-org/cluster-integration/gitlab-agent
# Namespace to use if not set explicitly in object manifest.
# Also used for inventory ConfigMap objects.
default_namespace: my-ns
# Paths inside of the repository to scan for manifest files.
# Directories with names starting with a dot are ignored.
@ -84,13 +85,13 @@ gitops:
# https://github.com/kubernetes/apimachinery/blob/44113beed5d39f1b261a12ec398a356e02358307/pkg/apis/meta/v1/types.go#L456-L470
# Can be: orphan, background, foreground
prune_propagation_policy: foreground # 'foreground' by default
# InventoryPolicy defines if an inventory object can take over
# Inventory policy defines if an inventory object can take over
# objects that belong to another inventory object or don't
# belong to any inventory object.
# This is done by determining if the apply/prune operation
# can go through for a resource based on the comparison
# the inventory-id value in the package and the owning-inventory
# annotation in the live object.
# annotation (config.k8s.io/owning-inventory) in the live object.
# https://github.com/kubernetes-sigs/cli-utils/blob/d6968048dcd80b1c7b55d9e4f31fc25f71c9b490/pkg/inventory/policy.go#L12-L66
# Can be: must_match, adopt_if_no_inventory, adopt_all
inventory_policy: must_match # 'must_match' by default

View file

@ -0,0 +1,69 @@
---
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
---
# Inventory object **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0.
An inventory object is a `ConfigMap` object for keeping track of the set of objects applied to a cluster.
When you remove objects from a manifest repository, GitLab Kubernetes Agent uses a corresponding inventory object to
prune (delete) objects from the cluster.
The GitLab Kubernetes Agent creates an inventory object for each manifest project specified in the
`gitops.manifest_projects` configuration section. The inventory object has to be stored somewhere in the cluster.
The default behavior is:
- The `namespace` used comes from `gitops.manifest_projects[].default_namespace`. If you don't specify this parameter
explicitly, the inventory object is stored in the `default` namespace.
- The `name` is generated from the numeric project ID of the manifest project and the numeric agent ID.
This way the GitLab Kubernetes Agent constructs the name and local where the inventory object is
stored in the cluster.
The GitLab Kubernetes Agent cannot locate the existing inventory object if you:
- Change `gitops.manifest_projects[].default_namespace` parameter.
- Move manifests into another project.
## Inventory object template
The inventory object template is a `ConfigMap` object that allows you to configure the namespace and the name of the inventory
object. Store this template with manifest files in a single group.
Example inventory object template:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: unique-name-for-the-inventory
namespace: my-project-namespace
labels:
cli-utils.sigs.k8s.io/inventory-id: unique-name-for-the-inventory
```
- The `namespace` and `name` fields configure where the real inventory object is created.
- The `cli-utils.sigs.k8s.io/inventory-id` label with its corresponding value is set on the inventory object, created
from this template. Make sure that the value is unique (for example, a string of random characters) and doesn't clash
with any existing or future inventory object templates.
- Objects tracked by this inventory object have the `config.k8s.io/owning-inventory` annotation set to the value of
the `cli-utils.sigs.k8s.io/inventory-id` label.
- The label's value doesn't have to match the `name` but it's convenient to have them set to the same value.
- Make sure that the `name` is unique so that it doesn't conflict with another inventory object in the same
namespace in the future.
## Using GitOps with pre-existing Kubernetes objects
The GitLab Kubernetes Agent treats manifest files in the manifest repository as the source of truth. When it applies
objects from the files to the cluster, it tracks them in an inventory object. If an object already exists,
GitLab Kubernetes Agent behaves differently based on the `gitops.manifest_projects[].inventory_policy` configuration.
Check the table below with the available options and when to use them.
`inventory_policy` value | Description |
------------------------ | ------------------------------------------------------------------------------------------- |
`must_match` | This is the default policy. A live object must have the `config.k8s.io/owning-inventory` annotation set to the same value as the `cli-utils.sigs.k8s.io/inventory-id` label on the corresponding inventory object to be updated. Object is not updated and an error is reported if the values don't match or the object doesn't have the annotation. |
`adopt_if_no_inventory` | This mode allows to "adopt" an object if it doesn't have the `config.k8s.io/owning-inventory` annotation. Use this mode if you want to start managing existing objects using the GitOps feature. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. |
`adopt_all` | This mode allows to "adopt" an object even if it has the `config.k8s.io/owning-inventory` annotation set to a different value. This mode can be useful if you want to migrate a set of objects from one agent to another one or from some other tool to the GitLab Kubernetes Agent. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. |

View file

@ -7,8 +7,8 @@ module BulkImports
DEFAULT_PAGE = 1
DEFAULT_PER_PAGE = 30
def initialize(uri:, token:, page: DEFAULT_PAGE, per_page: DEFAULT_PER_PAGE, api_version: API_VERSION)
@uri = URI.parse(uri)
def initialize(url:, token:, page: DEFAULT_PAGE, per_page: DEFAULT_PER_PAGE, api_version: API_VERSION)
@url = url
@token = token&.strip
@page = page
@per_page = per_page
@ -120,12 +120,8 @@ module BulkImports
raise(::BulkImports::Error, e)
end
def base_uri
@base_uri ||= "#{@uri.scheme}://#{@uri.host}:#{@uri.port}"
end
def api_url
Gitlab::Utils.append_path(base_uri, "/api/#{@api_version}")
Gitlab::Utils.append_path(@url, "/api/#{@api_version}")
end
end
end

View file

@ -25,7 +25,7 @@ module BulkImports
def http_client(configuration)
@http_client ||= BulkImports::Clients::HTTP.new(
uri: configuration.url,
url: configuration.url,
token: configuration.access_token,
per_page: 100
)

View file

@ -18,7 +18,7 @@ module BulkImports
def http_client(configuration)
@http_client ||= BulkImports::Clients::HTTP.new(
uri: configuration.url,
url: configuration.url,
token: configuration.access_token,
per_page: 100
)

View file

@ -63,10 +63,7 @@ module Gitlab
return users[username] if users.key?(username)
users[username] = User.select(:id)
.joins(:identities)
.find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username)
.try(:id)
users[username] = User.by_provider_and_extern_uid(:bitbucket, username).select(:id).first&.id
end
# rubocop: enable CodeReuse/ActiveRecord

View file

@ -138,7 +138,7 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def query_id_for_github_id(id)
User.for_github_id(id).pluck(:id).first
User.by_provider_and_extern_uid(:github, id).select(:id).first&.id
end
# rubocop: enable CodeReuse/ActiveRecord

View file

@ -56,8 +56,8 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def gitlab_user_id(project, gitlab_id)
user = User.joins(:identities).find_by("identities.extern_uid = ? AND identities.provider = 'gitlab'", gitlab_id.to_s)
(user && user.id) || project.creator_id
user_id = User.by_provider_and_extern_uid(:gitlab, gitlab_id).select(:id).first&.id
user_id || project.creator_id
end
# rubocop: enable CodeReuse/ActiveRecord
end

View file

@ -35,12 +35,7 @@ module Gitlab
def find_by_external_uid
return unless id
identities = ::Identity.arel_table
User.select(:id)
.joins(:identities)
.find_by(identities[:provider].eq(:github).and(identities[:extern_uid].eq(id)))
.try(:id)
User.by_provider_and_extern_uid(:github, id).select(:id).first&.id
end
# rubocop: enable CodeReuse/ActiveRecord
end

View file

@ -16187,6 +16187,9 @@ msgstr ""
msgid "Hide host keys manual input"
msgstr ""
msgid "Hide license key"
msgstr ""
msgid "Hide list"
msgstr ""
@ -17461,6 +17464,9 @@ msgstr ""
msgid "Install GitLab Runner on Kubernetes"
msgstr ""
msgid "Install license"
msgstr ""
msgid "Install on clusters"
msgstr ""
@ -30001,6 +30007,9 @@ msgstr ""
msgid "Show latest version"
msgstr ""
msgid "Show license key"
msgstr ""
msgid "Show links anyways"
msgstr ""
@ -38024,6 +38033,12 @@ msgstr ""
msgid "Your subscription will expire in %{remaining_days}."
msgstr ""
msgid "Your trial license was issued and activated. Install it to enjoy GitLab Ultimate for 30 days."
msgstr ""
msgid "Your trial license was issued!"
msgstr ""
msgid "Your username is %{username}."
msgstr ""

View file

@ -51,7 +51,7 @@ RSpec.describe Import::BulkImportsController do
end
describe 'GET status' do
let(:client) { BulkImports::Clients::HTTP.new(uri: 'http://gitlab.example', token: 'token') }
let(:client) { BulkImports::Clients::HTTP.new(url: 'http://gitlab.example', token: 'token') }
describe 'serialized group data' do
let(:client_response) do

View file

@ -31,7 +31,7 @@ RSpec.describe "Admin > Admin sees background migrations" do
end
end
it 'can view queued migrations' do
it 'can view queued migrations and pause and resume them' do
visit admin_background_migrations_path
within '#content-body' do
@ -40,7 +40,16 @@ RSpec.describe "Admin > Admin sees background migrations" do
expect(page).to have_content(active_migration.job_class_name)
expect(page).to have_content(active_migration.table_name)
expect(page).to have_content('0.00%')
expect(page).to have_content(active_migration.status.humanize)
expect(page).not_to have_content('Paused')
expect(page).to have_content('Active')
click_button('Pause')
expect(page).not_to have_content('Active')
expect(page).to have_content('Paused')
click_button('Resume')
expect(page).not_to have_content('Paused')
expect(page).to have_content('Active')
end
end

View file

@ -1,5 +1,7 @@
import { GlAlert } from '@gitlab/ui';
import { EditorContent } from '@tiptap/vue-2';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ContentEditor from '~/content_editor/components/content_editor.vue';
import TopToolbar from '~/content_editor/components/top_toolbar.vue';
import { createContentEditor } from '~/content_editor/services/create_content_editor';
@ -8,8 +10,11 @@ describe('ContentEditor', () => {
let wrapper;
let editor;
const findEditorElement = () => wrapper.findByTestId('content-editor');
const findErrorAlert = () => wrapper.findComponent(GlAlert);
const createWrapper = async (contentEditor) => {
wrapper = shallowMount(ContentEditor, {
wrapper = shallowMountExtended(ContentEditor, {
propsData: {
contentEditor,
},
@ -49,7 +54,7 @@ describe('ContentEditor', () => {
editor.tiptapEditor.isFocused = isFocused;
createWrapper(editor);
expect(wrapper.classes()).toStrictEqual(classes);
expect(findEditorElement().classes()).toStrictEqual(classes);
},
);
@ -57,6 +62,30 @@ describe('ContentEditor', () => {
editor.tiptapEditor.isFocused = true;
createWrapper(editor);
expect(wrapper.classes()).toContain('is-focused');
expect(findEditorElement().classes()).toContain('is-focused');
});
describe('displaying error', () => {
const error = 'Content Editor error';
beforeEach(async () => {
createWrapper(editor);
editor.tiptapEditor.emit('error', error);
await nextTick();
});
it('displays error notifications from the tiptap editor', () => {
expect(findErrorAlert().text()).toBe(error);
});
it('allows dismissing an error alert', async () => {
findErrorAlert().vm.$emit('dismiss');
await nextTick();
expect(findErrorAlert().exists()).toBe(false);
});
});
});

View file

@ -14,6 +14,7 @@ Object {
exports[`Grouped Issues List with data renders a report item with the correct props 1`] = `
Object {
"component": "TestIssueBody",
"iconComponent": "IssueStatusIcon",
"isNew": false,
"issue": Object {
"name": "foo",

View file

@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe BulkImports::Clients::HTTP do
include ImportSpecHelper
let(:uri) { 'http://gitlab.example' }
let(:url) { 'http://gitlab.example' }
let(:token) { 'token' }
let(:resource) { 'resource' }
let(:version) { "#{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}.0.0" }
@ -14,11 +14,11 @@ RSpec.describe BulkImports::Clients::HTTP do
before do
allow(Gitlab::HTTP).to receive(:get)
.with('http://gitlab.example:80/api/v4/version', anything)
.with('http://gitlab.example/api/v4/version', anything)
.and_return(version_response)
end
subject { described_class.new(uri: uri, token: token) }
subject { described_class.new(url: url, token: token) }
shared_examples 'performs network request' do
it 'performs network request' do
@ -54,7 +54,7 @@ RSpec.describe BulkImports::Clients::HTTP do
include_examples 'performs network request' do
let(:expected_args) do
[
'http://gitlab.example:80/api/v4/resource',
'http://gitlab.example/api/v4/resource',
hash_including(
follow_redirects: false,
query: {
@ -104,7 +104,7 @@ RSpec.describe BulkImports::Clients::HTTP do
private
def stub_http_get(path, query, response)
uri = "http://gitlab.example:80/api/v4/#{path}"
uri = "http://gitlab.example/api/v4/#{path}"
params = {
follow_redirects: false,
headers: {
@ -124,7 +124,7 @@ RSpec.describe BulkImports::Clients::HTTP do
include_examples 'performs network request' do
let(:expected_args) do
[
'http://gitlab.example:80/api/v4/resource',
'http://gitlab.example/api/v4/resource',
hash_including(
body: {},
follow_redirects: false,
@ -144,7 +144,7 @@ RSpec.describe BulkImports::Clients::HTTP do
include_examples 'performs network request' do
let(:expected_args) do
[
'http://gitlab.example:80/api/v4/resource',
'http://gitlab.example/api/v4/resource',
hash_including(
follow_redirects: false,
headers: {
@ -160,7 +160,7 @@ RSpec.describe BulkImports::Clients::HTTP do
describe '#stream' do
it 'performs network request with stream_body option' do
expected_args = [
'http://gitlab.example:80/api/v4/resource',
'http://gitlab.example/api/v4/resource',
hash_including(
stream_body: true,
headers: {
@ -183,4 +183,20 @@ RSpec.describe BulkImports::Clients::HTTP do
expect { subject.get(resource) }.to raise_error(::BulkImports::Error, "Unsupported GitLab Version. Minimum Supported Gitlab Version #{BulkImport::MINIMUM_GITLAB_MAJOR_VERSION}.")
end
end
context 'when url is relative' do
let(:url) { 'http://website.example/gitlab' }
before do
allow(Gitlab::HTTP).to receive(:get)
.with('http://website.example/gitlab/api/v4/version', anything)
.and_return(version_response)
end
it 'performs network request to a relative gitlab url' do
expect(Gitlab::HTTP).to receive(:get).with('http://website.example/gitlab/api/v4/resource', anything).and_return(response_double)
subject.get(resource)
end
end
end

View file

@ -5860,4 +5860,17 @@ RSpec.describe User do
end
end
end
describe '.by_provider_and_extern_uid' do
it 'calls Identity model scope to ensure case-insensitive query', :aggregate_failures do
expected_user = create(:user)
create(:identity, extern_uid: 'some-other-name-id', provider: :github)
create(:identity, extern_uid: 'my_github_id', provider: :gitlab)
create(:identity)
create(:identity, user: expected_user, extern_uid: 'my_github_id', provider: :github)
expect(Identity).to receive(:with_extern_uid).and_call_original
expect(described_class.by_provider_and_extern_uid(:github, 'my_github_id')).to match_array([expected_user])
end
end
end

View file

@ -29,7 +29,7 @@ class RequireMigration
migration_folders.flat_map do |path|
migration_path = Rails.root.join(path).to_s
Find.find(migration_path).grep(/\d+_#{file_name}\.rb/)
Find.find(migration_path).select { |m| File.basename(m).match? /\A\d+_#{file_name}\.rb\z/ }
end
end

View file

@ -6,7 +6,7 @@ RSpec.describe BulkImports::ExportRequestWorker do
let_it_be(:bulk_import) { create(:bulk_import) }
let_it_be(:config) { create(:bulk_import_configuration, bulk_import: bulk_import) }
let_it_be(:entity) { create(:bulk_import_entity, source_full_path: 'foo/bar', bulk_import: bulk_import) }
let_it_be(:version_url) { 'https://gitlab.example:443/api/v4/version' }
let_it_be(:version_url) { 'https://gitlab.example/api/v4/version' }
let(:response_double) { double(code: 200, success?: true, parsed_response: {}) }
let(:job_args) { [entity.id] }