Commit cc12468f authored by Andrew Fontaine's avatar Andrew Fontaine

Update Audit Logging for Feature Flags

Audit logging wasn't updated to audit log changes to feature flag
strategies, but needs to be now that legacy feature flags are in the
process of being removed.

Changelog: fixed
parent cc14366f
...@@ -48,10 +48,12 @@ module FeatureFlags ...@@ -48,10 +48,12 @@ module FeatureFlags
end end
end end
def created_scope_message(scope) def created_strategy_message(strategy)
"Created rule #{scope.environment_scope} "\ scopes = strategy.scopes
"and set it as #{scope.active ? "active" : "inactive"} "\ .map { |scope| %Q("#{scope.environment_scope}") }
"with strategies #{scope.strategies}." .join(', ')
%Q(Created strategy \"#{strategy.name}\" )\
"with scopes #{scopes}."
end end
def feature_flag_by_name def feature_flag_by_name
......
...@@ -24,8 +24,8 @@ module FeatureFlags ...@@ -24,8 +24,8 @@ module FeatureFlags
def audit_message(feature_flag) def audit_message(feature_flag)
message_parts = ["Created feature flag #{feature_flag.name} with description \"#{feature_flag.description}\"."] message_parts = ["Created feature flag #{feature_flag.name} with description \"#{feature_flag.description}\"."]
message_parts += feature_flag.scopes.map do |scope| message_parts += feature_flag.strategies.map do |strategy|
created_scope_message(scope) created_strategy_message(strategy)
end end
message_parts.join(" ") message_parts.join(" ")
......
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
module FeatureFlags module FeatureFlags
class UpdateService < FeatureFlags::BaseService class UpdateService < FeatureFlags::BaseService
AUDITABLE_SCOPE_ATTRIBUTES_HUMAN_NAMES = { AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES = {
'active' => 'active state', 'scopes' => 'environment scopes',
'environment_scope' => 'environment scope', 'parameters' => 'parameters'
'strategies' => 'strategies'
}.freeze }.freeze
def execute(feature_flag) def execute(feature_flag)
...@@ -41,7 +40,7 @@ module FeatureFlags ...@@ -41,7 +40,7 @@ module FeatureFlags
def audit_message(feature_flag) def audit_message(feature_flag)
changes = changed_attributes_messages(feature_flag) changes = changed_attributes_messages(feature_flag)
changes += changed_scopes_messages(feature_flag) changes += changed_strategies_messages(feature_flag)
return if changes.empty? return if changes.empty?
...@@ -56,29 +55,30 @@ module FeatureFlags ...@@ -56,29 +55,30 @@ module FeatureFlags
end end
end end
def changed_scopes_messages(feature_flag) def changed_strategies_messages(feature_flag)
feature_flag.scopes.map do |scope| feature_flag.strategies.map do |strategy|
if scope.new_record? if strategy.new_record?
created_scope_message(scope) created_strategy_message(strategy)
elsif scope.marked_for_destruction? elsif strategy.marked_for_destruction?
deleted_scope_message(scope) deleted_strategy_message(strategy)
else else
updated_scope_message(scope) updated_strategy_message(strategy)
end end
end.compact # updated_scope_message can return nil if nothing has been changed end.compact # updated_strategy_message can return nil if nothing has been changed
end end
def deleted_scope_message(scope) def deleted_strategy_message(strategy)
"Deleted rule #{scope.environment_scope}." scopes = strategy.scopes.map { |scope| scope.environment_scope }.join(', ')
"Deleted strategy #{strategy.name} with environment scopes #{scopes}."
end end
def updated_scope_message(scope) def updated_strategy_message(strategy)
changes = scope.changes.slice(*AUDITABLE_SCOPE_ATTRIBUTES_HUMAN_NAMES.keys) changes = strategy.changes.slice(*AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES.keys)
return if changes.empty? return if changes.empty?
message = "Updated rule #{scope.environment_scope} " message = "Updated strategy #{strategy.name} "
message += changes.map do |attribute_name, change| message += changes.map do |attribute_name, change|
name = AUDITABLE_SCOPE_ATTRIBUTES_HUMAN_NAMES[attribute_name] name = AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES[attribute_name]
"#{name} from #{change.first} to #{change.second}" "#{name} from #{change.first} to #{change.second}"
end.join(' ') end.join(' ')
......
...@@ -126,6 +126,7 @@ From there, you can see the following actions: ...@@ -126,6 +126,7 @@ From there, you can see the following actions:
- User password required for approvals was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2) - User password required for approvals was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
- Permission to modify merge requests approval rules in merge requests was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2) - Permission to modify merge requests approval rules in merge requests was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
- New approvals requirement when new commits are added to an MR was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2) - New approvals requirement when new commits are added to an MR was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
- When [strategies for feature flags](../operations/feature_flags.md#feature-flag-strategies) are changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68408) in GitLab 14.3)
Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events). Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events).
......
...@@ -48,8 +48,9 @@ RSpec.describe FeatureFlags::CreateService do ...@@ -48,8 +48,9 @@ RSpec.describe FeatureFlags::CreateService do
{ {
name: 'feature_flag', name: 'feature_flag',
description: 'description', description: 'description',
scopes_attributes: [{ environment_scope: '*', active: true }, version: 'new_version_flag',
{ environment_scope: 'production', active: false }] strategies_attributes: [{ name: 'default', scopes_attributes: [{ environment_scope: '*' }], parameters: {} },
{ name: 'default', parameters: {}, scopes_attributes: [{ environment_scope: 'production' }] }]
} }
end end
...@@ -70,10 +71,10 @@ RSpec.describe FeatureFlags::CreateService do ...@@ -70,10 +71,10 @@ RSpec.describe FeatureFlags::CreateService do
it 'creates audit event' do it 'creates audit event' do
expected_message = 'Created feature flag feature_flag '\ expected_message = 'Created feature flag feature_flag '\
'with description "description". '\ 'with description "description". '\
'Created rule * and set it as active '\ 'Created strategy "default" with scopes '\
'with strategies [{"name"=&gt;"default", "parameters"=&gt;{}}]. '\ '"*". '\
'Created rule production and set it as inactive '\ 'Created strategy "default" with scopes '\
'with strategies [{"name"=&gt;"default", "parameters"=&gt;{}}].' '"production".'
expect { subject }.to change { AuditEvent.count }.by(1) expect { subject }.to change { AuditEvent.count }.by(1)
expect(AuditEvent.last.details[:custom_message]).to eq(expected_message) expect(AuditEvent.last.details[:custom_message]).to eq(expected_message)
......
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