Commit 92f95cca authored by 🤖 GitLab Bot 🤖's avatar 🤖 GitLab Bot 🤖

Add latest changes from gitlab-org/[email protected]

parent 85e49493
......@@ -129,9 +129,6 @@ export default {
crossplaneInstalled() {
return this.applications.crossplane.status === APPLICATION_STATUS.INSTALLED;
},
enableClusterApplicationCrossplane() {
return gon.features && gon.features.enableClusterApplicationCrossplane;
},
enableClusterApplicationElasticStack() {
return gon.features && gon.features.enableClusterApplicationElasticStack;
},
......@@ -519,7 +516,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
</div>
</application-row>
<application-row
v-if="enableClusterApplicationCrossplane"
id="crossplane"
:logo-url="crossplaneLogo"
:title="applications.crossplane.title"
......
......@@ -82,6 +82,11 @@ export default {
required: false,
default: false,
},
pagesAccessControlForced: {
type: Boolean,
required: false,
default: false,
},
pagesHelpPath: {
type: String,
required: false,
......@@ -130,10 +135,22 @@ export default {
},
pagesFeatureAccessLevelOptions() {
if (this.visibilityLevel !== visibilityOptions.PUBLIC) {
return this.featureAccessLevelOptions.concat([[30, PAGE_FEATURE_ACCESS_LEVEL]]);
const options = [featureAccessLevelMembers];
if (this.pagesAccessControlForced) {
if (this.visibilityLevel === visibilityOptions.INTERNAL) {
options.push(featureAccessLevelEveryone);
}
} else {
if (this.visibilityLevel !== visibilityOptions.PRIVATE) {
options.push(featureAccessLevelEveryone);
}
if (this.visibilityLevel !== visibilityOptions.PUBLIC) {
options.push([30, PAGE_FEATURE_ACCESS_LEVEL]);
}
}
return this.featureAccessLevelOptions;
return options;
},
repositoryEnabled() {
......
......@@ -14,7 +14,7 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import Icon from '~/vue_shared/components/icon.vue';
import TableRegistry from './table_registry.vue';
import { DELETE_REPO_ERROR_MESSAGE } from '../constants';
import { __ } from '~/locale';
import { __, sprintf } from '~/locale';
export default {
name: 'CollapsibeContainerRegisty',
......@@ -55,6 +55,11 @@ export default {
canDeleteRepo() {
return this.repo.canDelete && !this.isDeleteDisabled;
},
deleteImageConfirmationMessage() {
return sprintf(__('Image %{imageName} was scheduled for deletion from the registry.'), {
imageName: this.repo.name,
});
},
},
methods: {
...mapActions(['fetchRepos', 'fetchList', 'deleteItem']),
......@@ -69,7 +74,7 @@ export default {
this.track('confirm_delete');
return this.deleteItem(this.repo)
.then(() => {
createFlash(__('This container registry has been scheduled for deletion.'), 'notice');
createFlash(this.deleteImageConfirmationMessage, 'notice');
this.fetchRepos();
})
.catch(() => createFlash(DELETE_REPO_ERROR_MESSAGE));
......
......@@ -14,7 +14,6 @@ class Clusters::ClustersController < Clusters::BaseController
before_action :update_applications_status, only: [:cluster_status]
before_action only: [:show] do
push_frontend_feature_flag(:enable_cluster_application_elastic_stack)
push_frontend_feature_flag(:enable_cluster_application_crossplane)
end
helper_method :token_in_session
......
......@@ -5,9 +5,6 @@ class SearchController < ApplicationController
include SearchHelper
include RendersCommits
NON_ES_SEARCH_TERM_LIMIT = 64
NON_ES_SEARCH_CHAR_LIMIT = 4096
around_action :allow_gitaly_ref_name_caching
skip_before_action :authenticate_user!
......@@ -68,19 +65,13 @@ class SearchController < ApplicationController
private
def search_term_valid?
return true if Gitlab::CurrentSettings.elasticsearch_search?
chars_count = params[:search].length
if chars_count > NON_ES_SEARCH_CHAR_LIMIT
flash[:alert] = t('errors.messages.search_chars_too_long', count: NON_ES_SEARCH_CHAR_LIMIT)
unless search_service.valid_query_length?
flash[:alert] = t('errors.messages.search_chars_too_long', count: SearchService::SEARCH_CHAR_LIMIT)
return false
end
search_terms_count = params[:search].split.count { |word| word.length >= 3 }
if search_terms_count > NON_ES_SEARCH_TERM_LIMIT
flash[:alert] = t('errors.messages.search_terms_too_long', count: NON_ES_SEARCH_TERM_LIMIT)
unless search_service.valid_terms_count?
flash[:alert] = t('errors.messages.search_terms_too_long', count: SearchService::SEARCH_TERM_LIMIT)
return false
end
......
......@@ -202,6 +202,7 @@ module ApplicationSettingsHelper
:enabled_git_access_protocol,
:enforce_terms,
:first_day_of_week,
:force_pages_access_control,
:gitaly_timeout_default,
:gitaly_timeout_medium,
:gitaly_timeout_fast,
......
......@@ -587,6 +587,7 @@ module ProjectsHelper
lfsHelpPath: help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs'),
pagesAvailable: Gitlab.config.pages.enabled,
pagesAccessControlEnabled: Gitlab.config.pages.access_control,
pagesAccessControlForced: ::Gitlab::Pages.access_control_is_forced?,
pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control-core')
}
end
......
......@@ -97,7 +97,13 @@ class ProjectFeature < ApplicationRecord
default_value_for :wiki_access_level, value: ENABLED, allows_nil: false
default_value_for :repository_access_level, value: ENABLED, allows_nil: false
default_value_for(:pages_access_level, allows_nil: false) { |feature| feature.project&.public? ? ENABLED : PRIVATE }
default_value_for(:pages_access_level, allows_nil: false) do |feature|
if ::Gitlab::Pages.access_control_is_forced?
PRIVATE
else
feature.project&.public? ? ENABLED : PRIVATE
end
end
def feature_available?(feature, user)
# This feature might not be behind a feature flag at all, so default to true
......@@ -137,6 +143,8 @@ class ProjectFeature < ApplicationRecord
def public_pages?
return true unless Gitlab.config.pages.access_control
return false if ::Gitlab::Pages.access_control_is_forced?
pages_access_level == PUBLIC || pages_access_level == ENABLED && project.public?
end
......
......@@ -68,7 +68,7 @@ module Clusters
end
def invalid_application?
unknown_application? || (application_name == Applications::ElasticStack.application_name && !Feature.enabled?(:enable_cluster_application_elastic_stack)) || (application_name == Applications::Crossplane.application_name && !Feature.enabled?(:enable_cluster_application_crossplane))
unknown_application? || (application_name == Applications::ElasticStack.application_name && !Feature.enabled?(:enable_cluster_application_elastic_stack))
end
def unknown_application?
......
......@@ -3,6 +3,9 @@
class SearchService
include Gitlab::Allowable
SEARCH_TERM_LIMIT = 64
SEARCH_CHAR_LIMIT = 4096
def initialize(current_user, params = {})
@current_user = current_user
@params = params.dup
......@@ -42,6 +45,14 @@ class SearchService
@show_snippets = params[:snippets] == 'true'
end
def valid_query_length?
params[:search].length <= SEARCH_CHAR_LIMIT
end
def valid_terms_count?
params[:search].split.count { |word| word.length >= 3 } <= SEARCH_TERM_LIMIT
end
delegate :scope, to: :search_service
def search_results
......
......@@ -15,6 +15,15 @@
.form-text.text-muted
= _("Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled")
= link_to icon('question-circle'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership')
- if Gitlab.config.pages.access_control
.form-group
.form-check
= f.check_box :force_pages_access_control, class: 'form-check-input'
= f.label :force_pages_access_control, class: 'form-check-label' do
= _("Disable public access to Pages sites")
.form-text.text-muted
= _("Access to Pages websites are controlled based on the user's membership to a given project. By checking this box, users will be required to be logged in to have access to all Pages websites in your instance.")
= link_to icon('question-circle'), help_page_path('administration/pages/index.md', anchor: 'disabling-public-access-to-all-pages-websites')
%h5
= _("Configure Let's Encrypt")
%p
......
---
title: Allow administrators to enforce access control for all pages web-sites
merge_request: 22003
author:
type: added
---
title: Pass log source to the frontend
merge_request: 22694
author:
type: changed
---
title: Enable ability to install Crossplane app by default
merge_request: 22141
author:
type: changed
---
title: Update auto-deploy-image to v0.8.3 for DAST default branch deploy
merge_request: 22227
author:
type: changed
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddForcePagesAccessControlToApplicationSettings < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
add_column :application_settings, :force_pages_access_control, :boolean, null: false, default: false
end
end
......@@ -364,6 +364,7 @@ ActiveRecord::Schema.define(version: 2020_01_08_233040) do
t.string "encrypted_slack_app_secret_iv", limit: 255
t.text "encrypted_slack_app_verification_token"
t.string "encrypted_slack_app_verification_token_iv", limit: 255
t.boolean "force_pages_access_control", default: false, null: false
t.boolean "updating_name_disabled_for_users", default: false, null: false
t.integer "instance_administrators_group_id"
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id"
......
......@@ -34,3 +34,11 @@ Read more in the [CI documentation](../ci/yaml/README.md#processing-git-pushes).
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/21164) in GitLab 8.12.
Activity history for projects and individuals' profiles was limited to one year until [GitLab 11.4](https://gitlab.com/gitlab-org/gitlab-foss/issues/52246) when it was extended to two years, and in [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/33840) to three years.
## Number of project webhooks
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/20730) in GitLab 12.6.
A maximum number of project webhooks applies to each GitLab.com tier. Check the
[Maximum number of webhooks (per tier)](../user/project/integrations/webhooks.md#maximum-number-of-webhooks-per-tier)
section in the Webhooks page.
......@@ -307,6 +307,27 @@ Pages access control is disabled by default. To enable it:
1. [Reconfigure GitLab][reconfigure].
1. Users can now configure it in their [projects' settings](../../user/project/pages/pages_access_control.md).
#### Disabling public access to all Pages websites
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32095) in GitLab 12.7.
You can enforce [Access Control](#access-control) for all GitLab Pages websites hosted
on your GitLab instance. By doing so, only logged-in users will have access to them.
This setting overrides Access Control set by users in individual projects.
This can be useful to preserve information published with Pages websites to the users
of your instance only.
To do that:
1. Navigate to your instance's **Admin Area > Settings > Preferences** and expand **Pages** settings.
1. Check the **Disable public access to Pages sites** checkbox.
1. Click **Save changes**.
CAUTION: **Warning:**
This action will not make all currently public web-sites private until they redeployed.
This issue among others will be resolved by
[changing GitLab Pages configuration mechanism](https://gitlab.com/gitlab-org/gitlab-pages/issues/282).
### Running behind a proxy
Like the rest of GitLab, Pages can be used in those environments where external
......
......@@ -72,6 +72,7 @@ description: 'Learn how to contribute to GitLab.'
- [Mass Inserting Models](mass_insert.md)
- [Cycle Analytics development guide](cycle_analytics.md)
- [Issue types vs first-class types](issue_types.md)
- [Application limits](application_limits.md)
## Performance guides
......
# Application limits development
This document provides a development guide for contributors to add application
limits to GitLab.
## Documentation
First of all, you have to gather information and decide which are the different
limits that will be set for the different GitLab tiers. You also need to
coordinate with others to [document](../administration/instance_limits.md)
and communicate those limits.
There is a guide about [introducing application
limits](https://about.gitlab.com/handbook/product/#introducing-application-limits).
## Development
The merge request to [configure maximum number of webhooks per
project](https://gitlab.com/gitlab-org/gitlab/merge_requests/20730/diffs) is a
good example about configuring application limits.
### Insert database plan limits
In the `plan_limits` table, you have to create a new column and insert the
limit values. It's recommended to create separate migration script files.
1. Add new column to the `plan_limits` table with non-null default value 0, eg:
```ruby
add_column(:plan_limits, :project_hooks, :integer, default: 0, null: false)
```
NOTE: **Note:** Plan limits entries set to `0` mean that limits are not
enabled.
1. Insert plan limits values into the database using
`create_or_update_plan_limit` migration helper, eg:
```ruby
create_or_update_plan_limit('project_hooks', 'free', 10)
create_or_update_plan_limit('project_hooks', 'bronze', 20)
create_or_update_plan_limit('project_hooks', 'silver', 30)
create_or_update_plan_limit('project_hooks', 'gold', 100)
```
### Plan limits validation
#### Get current limit
Access to the current limit can be done through the project or the namespace,
eg:
```ruby
project.actual_limits.project_hooks
```
#### Check current limit
There is one method `PlanLimits#exceeded?` to check if the current limit is
being exceeded. You can use either an `ActiveRecord` object or an `Integer`.
Ensures that the count of the records does not exceed the defined limit, eg:
```ruby
project.actual_limits.exceeded?(:project_hooks, ProjectHook.where(project: project))
```
Ensures that the number does not exceed the defined limit, eg:
```ruby
project.actual_limits.exceeded?(:project_hooks, 10)
```
#### `Limitable` concern
The [`Limitable` concern](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/models/concerns/ee/limitable.rb)
can be used to validate that a model does not exceed the limits. It ensures
that the count of the records for the current model does not exceed the defined
limit.
NOTE: **Note:** The name (pluralized) of the plan limit introduced in the
database (`project_hooks`) must correspond to the name of the model we are
validating (`ProjectHook`).
```ruby
class ProjectHook
include Limitable
end
```
......@@ -420,18 +420,6 @@ install Crossplane using the
[`values.yaml`](https://github.com/crossplaneio/crossplane/blob/master/cluster/charts/crossplane/values.yaml.tmpl)
file.
#### Enabling installation
This is a preliminary release of Crossplane as a GitLab-managed application. By default,
the ability to install it is disabled.
To allow installation of Crossplane as a GitLab-managed application, ask a GitLab
administrator to run following command within a Rails console:
```ruby
Feature.enable(:enable_cluster_application_crossplane)
```
### Elastic Stack
> Introduced in GitLab 12.7 for project- and group-level clusters.
......
......@@ -40,6 +40,7 @@ An epic's page contains the following tabs:
- **Epics and Issues**: epics and issues added to this epic. Child epics, and their issues, are shown in a tree view.
- Click on the <kbd>></kbd> beside a parent epic to reveal the child epics and issues.
- Hover over the total counts to see a breakdown of open and closed items.
- **Roadmap**: a roadmap view of child epics which have start and due dates.
![epic view](img/epic_view_v12.3.png)
......
......@@ -69,6 +69,8 @@ Data will be encoded with a comma as the column delimiter, with `"` used to quot
| Labels | Title of any labels joined with a `,` |
| Time Estimate | [Time estimate](../time_tracking.md#estimates) in seconds |
| Time Spent | [Time spent](../time_tracking.md#time-spent) in seconds |
| Epic ID | Id of the parent epic **(ULTIMATE)**, introduced in 12.7 |
| Epic Title | Title of the parent epic **(ULTIMATE)**, introduced in 12.7 |
## Limitations
......
......@@ -153,7 +153,7 @@ You can also edit an existing tag to add release notes:
![tags](img/tags_12_5.png "Addition of note to an existing tag")
## Release evidence
## Release Evidence
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26019) in GitLab 12.6.
......@@ -216,6 +216,22 @@ Here is what this object can look like:
}
```
### Enabling Release Evidence display **(CORE ONLY)**
This feature comes with the `:release_evidence_collection` feature flag
disabled by default in GitLab self-managed instances. To turn it on,
ask a GitLab administrator with Rails console access to run the following
command:
```ruby
Feature.enable(:release_evidence_collection)
```
NOTE: **Note:**
Please note that Release Evidence's data is collected regardless of this
feature flag, which only enables or disables the display of the data on the
Releases page.
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
.dast-auto-deploy:
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.6.0"
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.8.3"
dast_environment_deploy:
extends: .dast-auto-deploy
......
......@@ -18,6 +18,11 @@ module Gitlab
def secret_path
Gitlab.config.pages.secret_file
end
def access_control_is_forced?
::Gitlab.config.pages.access_control &&
::Gitlab::CurrentSettings.current_application_settings.force_pages_access_control
end
end
end
end
......@@ -332,6 +332,12 @@ msgstr ""
msgid "%{openOrClose} %{noteable}"
msgstr ""
msgid "%{openedEpics} open, %{closedEpics} closed"
msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
msgid "%{percent}%% complete"
msgstr ""
......@@ -841,6 +847,9 @@ msgstr ""
msgid "Access to '%{classification_label}' not allowed"
msgstr ""
msgid "Access to Pages websites are controlled based on the user's membership to a given project. By checking this box, users will be required to be logged in to have access to all Pages websites in your instance."
msgstr ""
msgid "AccessDropdown|Groups"
msgstr ""
......@@ -6318,6 +6327,9 @@ msgstr ""
msgid "Disable group Runners"
msgstr ""
msgid "Disable public access to Pages sites"
msgstr ""
msgid "Disable shared Runners"
msgstr ""
......@@ -6999,6 +7011,9 @@ msgstr ""
msgid "Environments|Environments are places where code gets deployed, such as staging or production."
msgstr ""
msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search."
msgstr ""
msgid "Environments|Job"
msgstr ""
......@@ -7119,9 +7134,6 @@ msgstr ""
msgid "Epics let you manage your portfolio of projects more efficiently and with less effort"
msgstr ""
msgid "Epics|%{epicsCount} epics and %{issuesCount} issues"
msgstr ""
msgid "Epics|Add an epic"
msgstr ""
......@@ -9754,6 +9766,9 @@ msgstr ""
msgid "Iglu registry URL (optional)"
msgstr ""
msgid "Image %{imageName} was scheduled for deletion from the registry."
msgstr ""
msgid "ImageDiffViewer|2-up"
msgstr ""
......@@ -18629,9 +18644,6 @@ msgstr ""
msgid "This commit was signed with an <strong>unverified</strong> signature."
msgstr ""
msgid "This container registry has been scheduled for deletion."
msgstr ""
msgid "This date is after the due date, so this epic won't appear in the roadmap."
msgstr ""
......@@ -20367,6 +20379,9 @@ msgstr ""
msgid "Very helpful"
msgstr ""
msgid "View Documentation"
msgstr ""
msgid "View app"
msgstr ""
......
......@@ -106,8 +106,8 @@ describe SearchController do
context 'check search term length' do
let(:search_queries) do
char_limit = controller.class::NON_ES_SEARCH_CHAR_LIMIT
term_limit = controller.class::NON_ES_SEARCH_TERM_LIMIT
char_limit = SearchService::SEARCH_CHAR_LIMIT
term_limit = SearchService::SEARCH_TERM_LIMIT
{
chars_under_limit: ('a' * (char_limit - 1)),
chars_over_limit: ('a' * (char_limit + 1)),
......@@ -116,21 +116,15 @@ describe SearchController do
}
end
where(:es_enabled, :string_name, :expectation) do
true | :chars_under_limit | :not_to_set_flash
true | :chars_over_limit | :not_to_set_flash
true | :terms_under_limit | :not_to_set_flash
true | :terms_over_limit | :not_to_set_flash
false | :chars_under_limit | :not_to_set_flash
false | :chars_over_limit | :set_chars_flash
false | :terms_under_limit | :not_to_set_flash
false | :terms_over_limit | :set_terms_flash
where(:string_name, :expectation) do
:chars_under_limit | :not_to_set_flash
:chars_over_limit | :set_chars_flash
:terms_under_limit | :not_to_set_flash
:terms_over_limit | :set_terms_flash
end
with_them do
it do
allow(Gitlab::CurrentSettings).to receive(:elasticsearch_search?).and_return(es_enabled)
get :show, params: { scope: 'projects', search: search_queries[string_name] }
case expectation
......
......@@ -17,7 +17,6 @@ describe('Applications', () => {
gon.features = gon.features || {};
gon.features.enableClusterApplicationElasticStack = true;
gon.features.enableClusterApplicationCrossplane = true;
});
afterEach(() => {
......
......@@ -89,19 +89,31 @@ describe('collapsible registry container', () => {
});
describe('delete repo', () => {
beforeEach(() => {
const deleteItem = jest.fn().mockResolvedValue();
const fetchRepos = jest.fn().mockResolvedValue();
wrapper.setMethods({ deleteItem, fetchRepos });
});
it('should be possible to delete a repo', () => {
const deleteBtn = findDeleteBtn();
expect(deleteBtn.exists()).toBe(true);
});
it('should call deleteItem when confirming deletion', () => {
const deleteItem = jest.fn().mockResolvedValue();
const fetchRepos = jest.fn().mockResolvedValue();
wrapper.setMethods({ deleteItem, fetchRepos });
wrapper.vm.handleDeleteRepository();
expect(wrapper.vm.deleteItem).toHaveBeenCalledWith(wrapper.vm.repo);
});
it('should show a flash with a success notice', () =>
wrapper.vm.handleDeleteRepository().then(() => {
expect(wrapper.vm.deleteImageConfirmationMessage).toContain(wrapper.vm.repo.name);
expect(createFlash).toHaveBeenCalledWith(
wrapper.vm.deleteImageConfirmationMessage,
'notice',
);
}));