gitlab-org--gitlab-foss/app/controllers/projects/feature_flags_controller.rb

175 lines
5.5 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
class Projects::FeatureFlagsController < Projects::ApplicationController
respond_to :html
before_action :authorize_read_feature_flag!
before_action :authorize_create_feature_flag!, only: [:new, :create]
before_action :authorize_update_feature_flag!, only: [:edit, :update]
before_action :authorize_destroy_feature_flag!, only: [:destroy]
before_action :feature_flag, only: [:edit, :update, :destroy]
before_action :ensure_legacy_flags_writable!, only: [:update]
before_action do
push_frontend_feature_flag(:feature_flag_permissions)
push_frontend_feature_flag(:feature_flags_new_version, project, default_enabled: true)
push_frontend_feature_flag(:feature_flags_legacy_read_only, project, default_enabled: true)
push_frontend_feature_flag(:feature_flags_legacy_read_only_override, project)
end
feature_category :feature_flags
def index
@feature_flags = FeatureFlagsFinder
.new(project, current_user, scope: params[:scope])
.execute
.page(params[:page])
.per(30)
respond_to do |format|
format.html
format.json do
Gitlab::PollingInterval.set_header(response, interval: 10_000)
render json: { feature_flags: feature_flags_json }.merge(summary_json)
end
end
end
def new
end
def show
respond_to do |format|
format.json do
Gitlab::PollingInterval.set_header(response, interval: 10_000)
render_success_json(feature_flag)
end
end
end
def create
result = FeatureFlags::CreateService.new(project, current_user, create_params).execute
if result[:status] == :success
respond_to do |format|
format.json { render_success_json(result[:feature_flag]) }
end
else
respond_to do |format|
format.json { render_error_json(result[:message]) }
end
end
end
def edit
end
def update
result = FeatureFlags::UpdateService.new(project, current_user, update_params).execute(feature_flag)
if result[:status] == :success
respond_to do |format|
format.json { render_success_json(result[:feature_flag]) }
end
else
respond_to do |format|
format.json { render_error_json(result[:message]) }
end
end
end
def destroy
result = FeatureFlags::DestroyService.new(project, current_user).execute(feature_flag)
if result[:status] == :success
respond_to do |format|
format.html { redirect_to_index(notice: _('Feature flag was successfully removed.')) }
format.json { render_success_json(feature_flag) }
end
else
respond_to do |format|
format.html { redirect_to_index(alert: _('Feature flag was not removed.')) }
format.json { render_error_json(result[:message]) }
end
end
end
protected
def feature_flag
@feature_flag ||= @noteable = if new_version_feature_flags_enabled?
project.operations_feature_flags.find_by_iid!(params[:iid])
else
project.operations_feature_flags.legacy_flag.find_by_iid!(params[:iid])
end
end
def new_version_feature_flags_enabled?
::Feature.enabled?(:feature_flags_new_version, project, default_enabled: true)
end
def ensure_legacy_flags_writable!
if ::Feature.enabled?(:feature_flags_legacy_read_only, project, default_enabled: true) &&
::Feature.disabled?(:feature_flags_legacy_read_only_override, project) &&
feature_flag.legacy_flag?
render_error_json(['Legacy feature flags are read-only'])
end
end
def create_params
params.require(:operations_feature_flag)
.permit(:name, :description, :active, :version,
scopes_attributes: [:environment_scope, :active,
strategies: [:name, parameters: [:groupId, :percentage, :userIds]]],
strategies_attributes: [:name, :user_list_id,
parameters: [:groupId, :percentage, :userIds, :rollout, :stickiness],
scopes_attributes: [:environment_scope]])
end
def update_params
params.require(:operations_feature_flag)
.permit(:name, :description, :active,
scopes_attributes: [:id, :environment_scope, :active, :_destroy,
strategies: [:name, parameters: [:groupId, :percentage, :userIds]]],
strategies_attributes: [:id, :name, :user_list_id, :_destroy,
parameters: [:groupId, :percentage, :userIds, :rollout, :stickiness],
scopes_attributes: [:id, :environment_scope, :_destroy]])
end
def feature_flag_json(feature_flag)
FeatureFlagSerializer
.new(project: @project, current_user: @current_user)
.represent(feature_flag)
end
def feature_flags_json
FeatureFlagSerializer
.new(project: @project, current_user: @current_user)
.with_pagination(request, response)
.represent(@feature_flags)
end
def summary_json
FeatureFlagSummarySerializer
.new(project: @project, current_user: @current_user)
.represent(@project)
end
def redirect_to_index(**args)
redirect_to project_feature_flags_path(@project), status: :found, **args
end
def render_success_json(feature_flag)
render json: feature_flag_json(feature_flag), status: :ok
end
def render_error_json(messages)
render json: { message: messages },
status: :bad_request
end
end