Commit b327db74 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch 'move-pipeline-configuration-ultimate' into 'master'

Add license check for group level compliance pipeline configuration

See merge request gitlab-org/gitlab!53182
parents 1527b64d 347ca5ff
...@@ -4129,7 +4129,8 @@ type ComplianceFramework { ...@@ -4129,7 +4129,8 @@ type ComplianceFramework {
""" """
Full path of the compliance pipeline configuration stored in a project Full path of the compliance pipeline configuration stored in a project
repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hippa`. repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa`
**(ULTIMATE)**.
""" """
pipelineConfigurationFullPath: String pipelineConfigurationFullPath: String
} }
...@@ -4187,7 +4188,8 @@ input ComplianceFrameworkInput { ...@@ -4187,7 +4188,8 @@ input ComplianceFrameworkInput {
""" """
Full path of the compliance pipeline configuration stored in a project Full path of the compliance pipeline configuration stored in a project
repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hippa`. repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa`
**(ULTIMATE)**.
""" """
pipelineConfigurationFullPath: String pipelineConfigurationFullPath: String
} }
......
...@@ -11284,7 +11284,7 @@ ...@@ -11284,7 +11284,7 @@
}, },
{ {
"name": "pipelineConfigurationFullPath", "name": "pipelineConfigurationFullPath",
"description": "Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hippa`.", "description": "Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa` **(ULTIMATE)**.",
"args": [ "args": [
], ],
...@@ -11454,7 +11454,7 @@ ...@@ -11454,7 +11454,7 @@
}, },
{ {
"name": "pipelineConfigurationFullPath", "name": "pipelineConfigurationFullPath",
"description": "Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hippa`.", "description": "Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa` **(ULTIMATE)**.",
"type": { "type": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "String",
...@@ -801,7 +801,7 @@ Represents a ComplianceFramework associated with a Project. ...@@ -801,7 +801,7 @@ Represents a ComplianceFramework associated with a Project.
| `description` | String! | Description of the compliance framework. | | `description` | String! | Description of the compliance framework. |
| `id` | ID! | Compliance framework ID. | | `id` | ID! | Compliance framework ID. |
| `name` | String! | Name of the compliance framework. | | `name` | String! | Name of the compliance framework. |
| `pipelineConfigurationFullPath` | String | Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hippa`. | | `pipelineConfigurationFullPath` | String | Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa` **(ULTIMATE)**. |
### ComposerMetadata ### ComposerMetadata
......
...@@ -24,7 +24,7 @@ module Types ...@@ -24,7 +24,7 @@ module Types
argument :pipeline_configuration_full_path, argument :pipeline_configuration_full_path,
GraphQL::STRING_TYPE, GraphQL::STRING_TYPE,
required: false, required: false,
description: 'Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hippa`.' description: 'Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa` **(ULTIMATE)**.'
end end
end end
end end
...@@ -25,7 +25,8 @@ module Types ...@@ -25,7 +25,8 @@ module Types
field :pipeline_configuration_full_path, GraphQL::STRING_TYPE, field :pipeline_configuration_full_path, GraphQL::STRING_TYPE,
null: true, null: true,
description: 'Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hippa`.' description: 'Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa` **(ULTIMATE)**.',
authorize: :manage_group_level_compliance_pipeline_config
end end
end end
end end
...@@ -148,6 +148,7 @@ class License < ApplicationRecord ...@@ -148,6 +148,7 @@ class License < ApplicationRecord
enforce_ssh_key_expiration enforce_ssh_key_expiration
enterprise_templates enterprise_templates
environment_alerts environment_alerts
evaluate_group_level_compliance_pipeline
group_ci_cd_analytics group_ci_cd_analytics
group_level_compliance_dashboard group_level_compliance_dashboard
incident_management incident_management
......
...@@ -9,8 +9,17 @@ module ComplianceManagement ...@@ -9,8 +9,17 @@ module ComplianceManagement
Feature.enabled?(:ff_custom_compliance_frameworks, @subject.namespace) Feature.enabled?(:ff_custom_compliance_frameworks, @subject.namespace)
end end
condition(:group_level_compliance_pipeline_enabled) do
@subject.namespace.feature_available?(:evaluate_group_level_compliance_pipeline) &&
Feature.enabled?(:ff_custom_compliance_frameworks, @subject.namespace)
end
rule { can?(:owner_access) & custom_compliance_frameworks_enabled }.policy do rule { can?(:owner_access) & custom_compliance_frameworks_enabled }.policy do
enable :manage_compliance_framework enable :manage_compliance_framework
end end
rule { can?(:owner_access) & group_level_compliance_pipeline_enabled }.policy do
enable :manage_group_level_compliance_pipeline_config
end
end end
end end
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
module ComplianceManagement module ComplianceManagement
module Frameworks module Frameworks
class CreateService < BaseService class CreateService < BaseService
include ::ComplianceManagement::Frameworks
attr_reader :namespace, :params, :current_user, :framework attr_reader :namespace, :params, :current_user, :framework
def initialize(namespace:, params:, current_user:) def initialize(namespace:, params:, current_user:)
...@@ -22,6 +24,7 @@ module ComplianceManagement ...@@ -22,6 +24,7 @@ module ComplianceManagement
) )
return ServiceResponse.error(message: 'Not permitted to create framework') unless permitted? return ServiceResponse.error(message: 'Not permitted to create framework') unless permitted?
return ServiceResponse.error(message: 'Pipeline configuration full path feature is not available') unless compliance_pipeline_configuration_available?
framework.save ? success : error framework.save ? success : error
end end
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
module ComplianceManagement module ComplianceManagement
module Frameworks module Frameworks
class UpdateService < BaseService class UpdateService < BaseService
include ::ComplianceManagement::Frameworks
attr_reader :framework, :current_user, :params attr_reader :framework, :current_user, :params
def initialize(framework:, current_user:, params:) def initialize(framework:, current_user:, params:)
...@@ -14,6 +16,11 @@ module ComplianceManagement ...@@ -14,6 +16,11 @@ module ComplianceManagement
def execute def execute
return error unless permitted? return error unless permitted?
unless compliance_pipeline_configuration_available?
framework.errors.add(:pipeline_configuration_full_path, 'feature is not available')
return error
end
framework.update(params) ? success : error framework.update(params) ? success : error
end end
......
# frozen_string_literal: true
module ComplianceManagement
module Frameworks
def compliance_pipeline_configuration_available?
return true unless params[:pipeline_configuration_full_path].present?
can? current_user, :manage_group_level_compliance_pipeline_config, framework
end
end
end
...@@ -27,7 +27,7 @@ RSpec.describe Mutations::ComplianceManagement::Frameworks::Create do ...@@ -27,7 +27,7 @@ RSpec.describe Mutations::ComplianceManagement::Frameworks::Create do
context 'feature is licensed' do context 'feature is licensed' do
before do before do
stub_licensed_features(custom_compliance_frameworks: true) stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: true)
end end
context 'feature flag is disabled' do context 'feature flag is disabled' do
...@@ -107,7 +107,7 @@ RSpec.describe Mutations::ComplianceManagement::Frameworks::Create do ...@@ -107,7 +107,7 @@ RSpec.describe Mutations::ComplianceManagement::Frameworks::Create do
name: 'GDPR', name: 'GDPR',
description: 'Example description', description: 'Example description',
color: '#abc123', color: '#abc123',
pipeline_configuration_full_path: 'compliance/.gitlab-ci.yml' pipeline_configuration_full_path: '.compliance-gitlab-ci.yml@compliance/hipaa'
} }
} }
end end
......
...@@ -10,11 +10,12 @@ RSpec.describe ComplianceManagement::FrameworkPolicy do ...@@ -10,11 +10,12 @@ RSpec.describe ComplianceManagement::FrameworkPolicy do
context 'feature is licensed' do context 'feature is licensed' do
before do before do
stub_licensed_features(custom_compliance_frameworks: true) stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: true)
end end
context 'user is namespace owner' do context 'user is namespace owner' do
it { is_expected.to be_allowed(:manage_compliance_framework) } it { is_expected.to be_allowed(:manage_compliance_framework) }
it { is_expected.to be_allowed(:manage_group_level_compliance_pipeline_config) }
end end
context 'user is group owner' do context 'user is group owner' do
...@@ -27,27 +28,31 @@ RSpec.describe ComplianceManagement::FrameworkPolicy do ...@@ -27,27 +28,31 @@ RSpec.describe ComplianceManagement::FrameworkPolicy do
end end
it { is_expected.to be_allowed(:manage_compliance_framework) } it { is_expected.to be_allowed(:manage_compliance_framework) }
it { is_expected.to be_allowed(:manage_group_level_compliance_pipeline_config) }
end end
context 'user is not namespace owner' do context 'user is not namespace owner' do
let(:user) { build(:user) } let(:user) { build(:user) }
it { is_expected.to be_disallowed(:manage_compliance_framework) } it { is_expected.to be_disallowed(:manage_compliance_framework) }
it { is_expected.to be_disallowed(:manage_group_level_compliance_pipeline_config) }
end end
context 'user is an admin', :enable_admin_mode do context 'user is an admin', :enable_admin_mode do
let(:user) { build(:admin) } let(:user) { build(:admin) }
it { is_expected.to be_allowed(:manage_compliance_framework) } it { is_expected.to be_allowed(:manage_compliance_framework) }
it { is_expected.to be_allowed(:manage_group_level_compliance_pipeline_config) }
end end
end end
context 'feature is unlicensed' do context 'feature is unlicensed' do
before do before do
stub_licensed_features(custom_compliance_frameworks: false) stub_licensed_features(custom_compliance_frameworks: false, evaluate_group_level_compliance_pipeline: false)
end end
it { is_expected.to be_disallowed(:manage_compliance_framework) } it { is_expected.to be_disallowed(:manage_compliance_framework) }
it { is_expected.to be_disallowed(:manage_group_level_compliance_pipeline_config) }
end end
context 'feature is disabled' do context 'feature is disabled' do
...@@ -56,5 +61,6 @@ RSpec.describe ComplianceManagement::FrameworkPolicy do ...@@ -56,5 +61,6 @@ RSpec.describe ComplianceManagement::FrameworkPolicy do
end end
it { is_expected.to be_disallowed(:manage_compliance_framework) } it { is_expected.to be_disallowed(:manage_compliance_framework) }
it { is_expected.to be_disallowed(:manage_group_level_compliance_pipeline_config) }
end end
end end
...@@ -16,7 +16,7 @@ RSpec.describe 'Create a Compliance Framework' do ...@@ -16,7 +16,7 @@ RSpec.describe 'Create a Compliance Framework' do
name: 'GDPR', name: 'GDPR',
description: 'Example Description', description: 'Example Description',
color: '#ABC123', color: '#ABC123',
pipeline_configuration_full_path: 'compliance/.gitlab-ci.yml' pipeline_configuration_full_path: '.compliance-gitlab-ci.yml@compliance/hipaa'
} }
) )
end end
...@@ -38,7 +38,7 @@ RSpec.describe 'Create a Compliance Framework' do ...@@ -38,7 +38,7 @@ RSpec.describe 'Create a Compliance Framework' do
expect(mutation_response['framework']['color']).to eq '#ABC123' expect(mutation_response['framework']['color']).to eq '#ABC123'
expect(mutation_response['framework']['name']).to eq 'GDPR' expect(mutation_response['framework']['name']).to eq 'GDPR'
expect(mutation_response['framework']['description']).to eq 'Example Description' expect(mutation_response['framework']['description']).to eq 'Example Description'
expect(mutation_response['framework']['pipelineConfigurationFullPath']).to eq 'compliance/.gitlab-ci.yml' expect(mutation_response['framework']['pipelineConfigurationFullPath']).to eq '.compliance-gitlab-ci.yml@compliance/hipaa'
end end
end end
...@@ -53,7 +53,7 @@ RSpec.describe 'Create a Compliance Framework' do ...@@ -53,7 +53,7 @@ RSpec.describe 'Create a Compliance Framework' do
context 'feature is licensed' do context 'feature is licensed' do
before do before do
stub_licensed_features(custom_compliance_frameworks: true) stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: true)
end end
context 'feature is disabled' do context 'feature is disabled' do
......
...@@ -13,8 +13,7 @@ RSpec.describe 'Update a compliance framework' do ...@@ -13,8 +13,7 @@ RSpec.describe 'Update a compliance framework' do
params: { params: {
name: 'New Name', name: 'New Name',
description: 'New Description', description: 'New Description',
color: '#AAC112', color: '#AAC112'
pipeline_configuration_full_path: 'compliance/.gitlab-ci.yml'
} }
} }
end end
...@@ -62,7 +61,36 @@ RSpec.describe 'Update a compliance framework' do ...@@ -62,7 +61,36 @@ RSpec.describe 'Update a compliance framework' do
expect(mutation_response['complianceFramework']['name']).to eq 'New Name' expect(mutation_response['complianceFramework']['name']).to eq 'New Name'
expect(mutation_response['complianceFramework']['description']).to eq 'New Description' expect(mutation_response['complianceFramework']['description']).to eq 'New Description'
expect(mutation_response['complianceFramework']['color']).to eq '#AAC112' expect(mutation_response['complianceFramework']['color']).to eq '#AAC112'
expect(mutation_response['complianceFramework']['pipelineConfigurationFullPath']).to eq 'compliance/.gitlab-ci.yml' end
context 'pipeline configuration full path' do
before do
params[:params][:pipeline_configuration_full_path] = '.compliance-gitlab-ci.yml@compliance/hipaa'
end
context 'when compliance pipeline configuration feature is available' do
before do
stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: true)
end
it 'updates the pipeline configuration path attribute' do
subject
expect(mutation_response['complianceFramework']['pipelineConfigurationFullPath']).to eq '.compliance-gitlab-ci.yml@compliance/hipaa'
end
end
context 'when compliance pipeline configuration feature is not available' do
before do
stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: false)
end
it 'returns an error' do
subject
expect(mutation_response['errors']).to contain_exactly "Pipeline configuration full path feature is not available"
end
end
end end
context 'current_user is not permitted to update framework' do context 'current_user is not permitted to update framework' do
......
...@@ -8,8 +8,7 @@ RSpec.describe ComplianceManagement::Frameworks::CreateService do ...@@ -8,8 +8,7 @@ RSpec.describe ComplianceManagement::Frameworks::CreateService do
{ {
name: 'GDPR', name: 'GDPR',
description: 'The EUs data protection directive', description: 'The EUs data protection directive',
color: '#abc123', color: '#abc123'
pipeline_configuration_full_path: 'compliance/.gitlab-ci.yml'
} }
end end
...@@ -72,6 +71,22 @@ RSpec.describe ComplianceManagement::Frameworks::CreateService do ...@@ -72,6 +71,22 @@ RSpec.describe ComplianceManagement::Frameworks::CreateService do
end end
end end
context 'when pipeline_configuration_full_path parameter is used and feature is not available' do
subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) }
before do
params[:pipeline_configuration_full_path] = '.compliance-gitlab-ci.yml@compliance/hipaa'
stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: false)
end
let(:response) { subject.execute }
it 'returns an error', :aggregate_failures do
expect(response.success?).to be false
expect(response.message).to eq 'Pipeline configuration full path feature is not available'
end
end
context 'when using parameters for a valid compliance framework' do context 'when using parameters for a valid compliance framework' do
subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) } subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) }
...@@ -89,7 +104,19 @@ RSpec.describe ComplianceManagement::Frameworks::CreateService do ...@@ -89,7 +104,19 @@ RSpec.describe ComplianceManagement::Frameworks::CreateService do
expect(framework.name).to eq('GDPR') expect(framework.name).to eq('GDPR')
expect(framework.description).to eq('The EUs data protection directive') expect(framework.description).to eq('The EUs data protection directive')
expect(framework.color).to eq('#abc123') expect(framework.color).to eq('#abc123')
expect(framework.pipeline_configuration_full_path).to eq('compliance/.gitlab-ci.yml') end
context 'when compliance pipeline configuration is available' do
before do
params[:pipeline_configuration_full_path] = '.compliance-gitlab-ci.yml@compliance/hipaa'
stub_licensed_features(custom_compliance_frameworks: true, evaluate_group_level_compliance_pipeline: true)
end
it 'sets the pipeline configuration path attribute' do
framework = subject.execute.payload[:framework]
expect(framework.pipeline_configuration_full_path).to eq('.compliance-gitlab-ci.yml@compliance/hipaa')
end
end end
end end
end end
......
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