summaryrefslogtreecommitdiff
path: root/app/services/admin/set_feature_flag_service.rb
blob: d72a18a6a5814a04d0e35cefa2448c9df273afc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# frozen_string_literal: true

module Admin
  class SetFeatureFlagService
    def initialize(feature_flag_name:, params:)
      @name = feature_flag_name
      @params = params
    end

    def execute
      unless params[:force]
        error = validate_feature_flag_name
        return ServiceResponse.error(message: error, reason: :invalid_feature_flag) if error
      end

      flag_target = Feature::Target.new(params)
      value = gate_value(params)

      case value
      when true
        enable!(flag_target)
      when false
        disable!(flag_target)
      else
        enable_partially!(value, params)
      end

      feature_flag = Feature.get(name) # rubocop:disable Gitlab/AvoidFeatureGet

      ServiceResponse.success(payload: { feature_flag: feature_flag })
    rescue Feature::Target::UnknowTargetError => e
      ServiceResponse.error(message: e.message, reason: :actor_not_found)
    end

    private

    attr_reader :name, :params

    def enable!(flag_target)
      if flag_target.gate_specified?
        flag_target.targets.each { |target| Feature.enable(name, target) }
      else
        Feature.enable(name)
      end
    end

    def disable!(flag_target)
      if flag_target.gate_specified?
        flag_target.targets.each { |target| Feature.disable(name, target) }
      else
        Feature.disable(name)
      end
    end

    def enable_partially!(value, params)
      if params[:key] == 'percentage_of_actors'
        Feature.enable_percentage_of_actors(name, value)
      else
        Feature.enable_percentage_of_time(name, value)
      end
    end

    def validate_feature_flag_name
      # overridden in EE
    end

    def gate_value(params)
      case params[:value]
      when 'true'
        true
      when '0', 'false'
        false
      else
        # https://github.com/jnunemaker/flipper/blob/master/lib/flipper/typecast.rb#L47
        if params[:value].to_s.include?('.')
          params[:value].to_f
        else
          params[:value].to_i
        end
      end
    end
  end
end

Admin::SetFeatureFlagService.prepend_mod