Commit ad1824fc authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 5fbbc478 02f8eadd
...@@ -48,7 +48,12 @@ export default (elements) => { ...@@ -48,7 +48,12 @@ export default (elements) => {
Vue.use(VueApollo); Vue.use(VueApollo);
const apolloProvider = new VueApollo({ const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(), defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
}); });
const listenerAddedAttr = 'data-mr-listener-added'; const listenerAddedAttr = 'data-mr-listener-added';
......
...@@ -140,9 +140,7 @@ export default { ...@@ -140,9 +140,7 @@ export default {
<div <div
class="gl-mt-2 gl-mb-2 align-content-around align-items-start flex-wrap align-self-center d-flex" class="gl-mt-2 gl-mb-2 align-content-around align-items-start flex-wrap align-self-center d-flex"
> >
<div class="gl-mr-4"> <div v-safe-html="data.text" class="gl-mr-4"></div>
{{ data.text }}
</div>
<div v-if="data.link"> <div v-if="data.link">
<gl-link :href="data.link.href">{{ data.link.text }}</gl-link> <gl-link :href="data.link.href">{{ data.link.text }}</gl-link>
</div> </div>
......
...@@ -379,6 +379,18 @@ Some [known database inconsistency issues](#known-issues) exist in Gitaly Cluste ...@@ -379,6 +379,18 @@ Some [known database inconsistency issues](#known-issues) exist in Gitaly Cluste
remain on your current service for now. We can adjust the date for remain on your current service for now. We can adjust the date for
[NFS support removal](#nfs-deprecation-notice) if this applies to you. [NFS support removal](#nfs-deprecation-notice) if this applies to you.
### Migrate off Gitaly Cluster
If you have repositories stored on a Gitaly Cluster, but you'd like to migrate
them back to direct Gitaly storage:
1. Create and configure a new
[Gitaly server](configure_gitaly.md#run-gitaly-on-its-own-server).
1. [Move the repositories](../operations/moving_repositories.md#move-repositories)
to the newly created storage. There are different possibilities to move them
by shard or by group, this gives you the opportunity to spread them over
multiple Gitaly servers.
## Monitor Gitaly and Gitaly Cluster ## Monitor Gitaly and Gitaly Cluster
You can use the available logs and [Prometheus metrics](../monitoring/prometheus/index.md) to You can use the available logs and [Prometheus metrics](../monitoring/prometheus/index.md) to
......
# frozen_string_literal: true
module AppSec
module Dast
module SiteProfileSecretVariables
class CreateOrUpdateService < BaseContainerService
def execute
return error_response('Insufficient permissions') unless allowed?
return error_response('Dast site profile param is missing') unless site_profile
return error_response('Key param is missing') unless key
return error_response('Raw value param is missing') unless raw_value
secret_variable = find_or_create_secret_variable
return error_response(secret_variable.errors.full_messages) unless secret_variable.valid? && secret_variable.persisted?
success_response(secret_variable)
end
private
def allowed?
Ability.allowed?(current_user, :create_on_demand_dast_scan, container)
end
def site_profile
params[:dast_site_profile]
end
def key
params[:key]
end
def raw_value
params[:raw_value]
end
def success_response(secret_variable)
ServiceResponse.success(payload: secret_variable)
end
def error_response(message)
ServiceResponse.error(message: message)
end
# rubocop: disable CodeReuse/ActiveRecord
def find_or_create_secret_variable
secret_variable = ::Dast::SiteProfileSecretVariable.find_or_initialize_by(dast_site_profile: site_profile, key: key)
secret_variable.update(raw_value: raw_value)
secret_variable
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
end
end
# frozen_string_literal: true
module AppSec
module Dast
module SiteProfileSecretVariables
class DestroyService < BaseContainerService
def execute
return ServiceResponse.error(message: 'Insufficient permissions') unless allowed?
return ServiceResponse.error(message: 'Variable parameter missing') unless dast_site_profile_secret_variable
return ServiceResponse.error(message: 'Variable failed to delete') unless dast_site_profile_secret_variable.destroy
ServiceResponse.success(payload: dast_site_profile_secret_variable)
end
private
def allowed?
Ability.allowed?(current_user, :create_on_demand_dast_scan, container)
end
def dast_site_profile_secret_variable
params[:dast_site_profile_secret_variable]
end
end
end
end
end
...@@ -51,7 +51,7 @@ module AppSec ...@@ -51,7 +51,7 @@ module AppSec
def create_secret_variable!(key, value) def create_secret_variable!(key, value)
return ServiceResponse.success unless value return ServiceResponse.success unless value
response = ::Dast::SiteProfileSecretVariables::CreateOrUpdateService.new( response = ::AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService.new(
container: project, container: project,
current_user: current_user, current_user: current_user,
params: { dast_site_profile: dast_site_profile, key: key, raw_value: value } params: { dast_site_profile: dast_site_profile, key: key, raw_value: value }
......
...@@ -73,7 +73,7 @@ module AppSec ...@@ -73,7 +73,7 @@ module AppSec
return delete_secret_variable!(key) if value == '' return delete_secret_variable!(key) if value == ''
response = ::Dast::SiteProfileSecretVariables::CreateOrUpdateService.new( response = ::AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService.new(
container: project, container: project,
current_user: current_user, current_user: current_user,
params: { dast_site_profile: dast_site_profile, key: key, raw_value: value } params: { dast_site_profile: dast_site_profile, key: key, raw_value: value }
...@@ -90,7 +90,7 @@ module AppSec ...@@ -90,7 +90,7 @@ module AppSec
return ServiceResponse.success unless variable return ServiceResponse.success unless variable
response = ::Dast::SiteProfileSecretVariables::DestroyService.new( response = ::AppSec::Dast::SiteProfileSecretVariables::DestroyService.new(
container: project, container: project,
current_user: current_user, current_user: current_user,
params: { dast_site_profile_secret_variable: variable } params: { dast_site_profile_secret_variable: variable }
......
# frozen_string_literal: true
module Dast
module SiteProfileSecretVariables
class CreateOrUpdateService < BaseContainerService
def execute
return error_response('Insufficient permissions') unless allowed?
return error_response('Dast site profile param is missing') unless site_profile
return error_response('Key param is missing') unless key
return error_response('Raw value param is missing') unless raw_value
secret_variable = find_or_create_secret_variable
return error_response(secret_variable.errors.full_messages) unless secret_variable.valid? && secret_variable.persisted?
success_response(secret_variable)
end
private
def allowed?
Ability.allowed?(current_user, :create_on_demand_dast_scan, container)
end
def site_profile
params[:dast_site_profile]
end
def key
params[:key]
end
def raw_value
params[:raw_value]
end
def success_response(secret_variable)
ServiceResponse.success(payload: secret_variable)
end
def error_response(message)
ServiceResponse.error(message: message)
end
# rubocop: disable CodeReuse/ActiveRecord
def find_or_create_secret_variable
secret_variable = Dast::SiteProfileSecretVariable.find_or_initialize_by(dast_site_profile: site_profile, key: key)
secret_variable.update(raw_value: raw_value)
secret_variable
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
end
# frozen_string_literal: true
module Dast
module SiteProfileSecretVariables
class DestroyService < BaseContainerService
def execute
return ServiceResponse.error(message: 'Insufficient permissions') unless allowed?
return ServiceResponse.error(message: 'Variable parameter missing') unless dast_site_profile_secret_variable
return ServiceResponse.error(message: 'Variable failed to delete') unless dast_site_profile_secret_variable.destroy
ServiceResponse.success(payload: dast_site_profile_secret_variable)
end
private
def allowed?
Ability.allowed?(current_user, :create_on_demand_dast_scan, container)
end
def dast_site_profile_secret_variable
params[:dast_site_profile_secret_variable]
end
end
end
end
...@@ -129,10 +129,10 @@ RSpec.describe Mutations::DastSiteProfiles::Create do ...@@ -129,10 +129,10 @@ RSpec.describe Mutations::DastSiteProfiles::Create do
context 'when variable creation fails' do context 'when variable creation fails' do
it 'returns an error and the dast_site_profile' do it 'returns an error and the dast_site_profile' do
service = double(Dast::SiteProfileSecretVariables::CreateOrUpdateService) service = double(AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService)
result = ServiceResponse.error(payload: create(:dast_site_profile), message: 'Oops') result = ServiceResponse.error(payload: create(:dast_site_profile), message: 'Oops')
allow(Dast::SiteProfileSecretVariables::CreateOrUpdateService).to receive(:new).and_return(service) allow(AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService).to receive(:new).and_return(service)
allow(service).to receive(:execute).and_return(result) allow(service).to receive(:execute).and_return(result)
expect(subject).to include(errors: ['Oops']) expect(subject).to include(errors: ['Oops'])
......
...@@ -146,10 +146,10 @@ RSpec.describe Mutations::DastSiteProfiles::Update do ...@@ -146,10 +146,10 @@ RSpec.describe Mutations::DastSiteProfiles::Update do
context 'when variable creation fails' do context 'when variable creation fails' do
it 'returns an error and the dast_site_profile' do it 'returns an error and the dast_site_profile' do
service = double(Dast::SiteProfileSecretVariables::CreateOrUpdateService) service = double(AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService)
result = ServiceResponse.error(payload: create(:dast_site_profile), message: 'Oops') result = ServiceResponse.error(payload: create(:dast_site_profile), message: 'Oops')
allow(Dast::SiteProfileSecretVariables::CreateOrUpdateService).to receive(:new).and_return(service) allow(AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService).to receive(:new).and_return(service)
allow(service).to receive(:execute).and_return(result) allow(service).to receive(:execute).and_return(result)
expect(subject).to include(errors: ['Oops']) expect(subject).to include(errors: ['Oops'])
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Dast::SiteProfileSecretVariables::CreateOrUpdateService do RSpec.describe AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let_it_be(:dast_profile) { create(:dast_profile, project: project) } let_it_be(:dast_profile) { create(:dast_profile, project: project) }
let_it_be(:developer) { create(:user, developer_projects: [project] ) } let_it_be(:developer) { create(:user, developer_projects: [project] ) }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Dast::SiteProfileSecretVariables::DestroyService do RSpec.describe AppSec::Dast::SiteProfileSecretVariables::DestroyService do
include GraphqlHelpers include GraphqlHelpers
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
......
...@@ -150,7 +150,7 @@ RSpec.describe AppSec::Dast::SiteProfiles::CreateService do ...@@ -150,7 +150,7 @@ RSpec.describe AppSec::Dast::SiteProfiles::CreateService do
shared_examples 'it handles secret variable creation failure' do shared_examples 'it handles secret variable creation failure' do
before do before do
allow_next_instance_of(Dast::SiteProfileSecretVariables::CreateOrUpdateService) do |service| allow_next_instance_of(AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService) do |service|
response = ServiceResponse.error(message: 'Something went wrong') response = ServiceResponse.error(message: 'Something went wrong')
allow(service).to receive(:execute).and_return(response) allow(service).to receive(:execute).and_return(response)
......
...@@ -184,7 +184,7 @@ RSpec.describe AppSec::Dast::SiteProfiles::UpdateService do ...@@ -184,7 +184,7 @@ RSpec.describe AppSec::Dast::SiteProfiles::UpdateService do
shared_examples 'it handles secret variable updating failure' do shared_examples 'it handles secret variable updating failure' do
before do before do
allow_next_instance_of(Dast::SiteProfileSecretVariables::CreateOrUpdateService) do |service| allow_next_instance_of(AppSec::Dast::SiteProfileSecretVariables::CreateOrUpdateService) do |service|
response = ServiceResponse.error(message: 'Something went wrong') response = ServiceResponse.error(message: 'Something went wrong')
allow(service).to receive(:execute).and_return(response) allow(service).to receive(:execute).and_return(response)
......
...@@ -25,7 +25,7 @@ module Backup ...@@ -25,7 +25,7 @@ module Backup
args += ['-parallel', @parallel.to_s] if @parallel args += ['-parallel', @parallel.to_s] if @parallel
args += ['-parallel-storage', @parallel_storage.to_s] if @parallel_storage args += ['-parallel-storage', @parallel_storage.to_s] if @parallel_storage
@stdin, stdout, @thread = Open3.popen2(ENV, bin_path, command, '-path', backup_repos_path, *args) @stdin, stdout, @thread = Open3.popen2(build_env, bin_path, command, '-path', backup_repos_path, *args)
@out_reader = Thread.new do @out_reader = Thread.new do
IO.copy_stream(stdout, @progress) IO.copy_stream(stdout, @progress)
...@@ -63,6 +63,13 @@ module Backup ...@@ -63,6 +63,13 @@ module Backup
private private
def build_env
{
'SSL_CERT_FILE' => OpenSSL::X509::DEFAULT_CERT_FILE,
'SSL_CERT_DIR' => OpenSSL::X509::DEFAULT_CERT_DIR
}.merge(ENV)
end
def started? def started?
@thread.present? @thread.present?
end end
......
...@@ -5,12 +5,20 @@ require 'spec_helper' ...@@ -5,12 +5,20 @@ require 'spec_helper'
RSpec.describe Backup::GitalyBackup do RSpec.describe Backup::GitalyBackup do
let(:parallel) { nil } let(:parallel) { nil }
let(:parallel_storage) { nil } let(:parallel_storage) { nil }
let(:progress) do let(:progress) do
Tempfile.new('progress').tap do |progress| Tempfile.new('progress').tap do |progress|
progress.unlink progress.unlink
end end
end end
let(:expected_env) do
{
'SSL_CERT_FILE' => OpenSSL::X509::DEFAULT_CERT_FILE,
'SSL_CERT_DIR' => OpenSSL::X509::DEFAULT_CERT_DIR
}.merge(ENV)
end
after do after do
progress.close progress.close
end end
...@@ -32,7 +40,7 @@ RSpec.describe Backup::GitalyBackup do ...@@ -32,7 +40,7 @@ RSpec.describe Backup::GitalyBackup do
project_snippet = create(:project_snippet, :repository, project: project) project_snippet = create(:project_snippet, :repository, project: project)
personal_snippet = create(:personal_snippet, :repository, author: project.owner) personal_snippet = create(:personal_snippet, :repository, author: project.owner)
expect(Open3).to receive(:popen2).with(ENV, anything, 'create', '-path', anything).and_call_original expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything).and_call_original
subject.start(:create) subject.start(:create)
subject.enqueue(project, Gitlab::GlRepository::PROJECT) subject.enqueue(project, Gitlab::GlRepository::PROJECT)
...@@ -53,7 +61,7 @@ RSpec.describe Backup::GitalyBackup do ...@@ -53,7 +61,7 @@ RSpec.describe Backup::GitalyBackup do
let(:parallel) { 3 } let(:parallel) { 3 }
it 'passes parallel option through' do it 'passes parallel option through' do
expect(Open3).to receive(:popen2).with(ENV, anything, 'create', '-path', anything, '-parallel', '3').and_call_original expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything, '-parallel', '3').and_call_original
subject.start(:create) subject.start(:create)
subject.wait subject.wait
...@@ -64,7 +72,7 @@ RSpec.describe Backup::GitalyBackup do ...@@ -64,7 +72,7 @@ RSpec.describe Backup::GitalyBackup do
let(:parallel_storage) { 3 } let(:parallel_storage) { 3 }
it 'passes parallel option through' do it 'passes parallel option through' do
expect(Open3).to receive(:popen2).with(ENV, anything, 'create', '-path', anything, '-parallel-storage', '3').and_call_original expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything, '-parallel-storage', '3').and_call_original
subject.start(:create) subject.start(:create)
subject.wait subject.wait
...@@ -90,6 +98,26 @@ RSpec.describe Backup::GitalyBackup do ...@@ -90,6 +98,26 @@ RSpec.describe Backup::GitalyBackup do
it_behaves_like 'creates a repository backup' it_behaves_like 'creates a repository backup'
end end
context 'custom SSL envs set' do
let(:ssl_env) do
{
'SSL_CERT_FILE' => '/some/cert/file',
'SSL_CERT_DIR' => '/some/cert'
}
end
before do
stub_const('ENV', ssl_env)
end
it 'passes through SSL envs' do
expect(Open3).to receive(:popen2).with(ssl_env, anything, 'create', '-path', anything).and_call_original
subject.start(:create)
subject.wait
end
end
end end
context 'restore' do context 'restore' do
...@@ -109,7 +137,7 @@ RSpec.describe Backup::GitalyBackup do ...@@ -109,7 +137,7 @@ RSpec.describe Backup::GitalyBackup do
copy_bundle_to_backup_path('personal_snippet_repo.bundle', personal_snippet.disk_path + '.bundle') copy_bundle_to_backup_path('personal_snippet_repo.bundle', personal_snippet.disk_path + '.bundle')
copy_bundle_to_backup_path('project_snippet_repo.bundle', project_snippet.disk_path + '.bundle') copy_bundle_to_backup_path('project_snippet_repo.bundle', project_snippet.disk_path + '.bundle')
expect(Open3).to receive(:popen2).with(ENV, anything, 'restore', '-path', anything).and_call_original expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything).and_call_original
subject.start(:restore) subject.start(:restore)
subject.enqueue(project, Gitlab::GlRepository::PROJECT) subject.enqueue(project, Gitlab::GlRepository::PROJECT)
...@@ -132,7 +160,7 @@ RSpec.describe Backup::GitalyBackup do ...@@ -132,7 +160,7 @@ RSpec.describe Backup::GitalyBackup do
let(:parallel) { 3 } let(:parallel) { 3 }
it 'passes parallel option through' do it 'passes parallel option through' do
expect(Open3).to receive(:popen2).with(ENV, anything, 'restore', '-path', anything, '-parallel', '3').and_call_original expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-parallel', '3').and_call_original
subject.start(:restore) subject.start(:restore)
subject.wait subject.wait
...@@ -143,7 +171,7 @@ RSpec.describe Backup::GitalyBackup do ...@@ -143,7 +171,7 @@ RSpec.describe Backup::GitalyBackup do
let(:parallel_storage) { 3 } let(:parallel_storage) { 3 }
it 'passes parallel option through' do it 'passes parallel option through' do
expect(Open3).to receive(:popen2).with(ENV, anything, 'restore', '-path', anything, '-parallel-storage', '3').and_call_original expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-parallel-storage', '3').and_call_original
subject.start(:restore) subject.start(:restore)
subject.wait subject.wait
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment