1# frozen_string_literal: true 2 3module Atlassian 4 module JiraConnect 5 module Serializers 6 class FeatureFlagEntity < Grape::Entity 7 include Gitlab::Routing 8 9 alias_method :flag, :object 10 11 format_with(:string, &:to_s) 12 13 expose :schema_version, as: :schemaVersion 14 expose :id, format_with: :string 15 expose :name, as: :key 16 expose :update_sequence_id, as: :updateSequenceId 17 expose :name, as: :displayName 18 expose :summary 19 expose :details 20 expose :issue_keys, as: :issueKeys 21 22 def issue_keys 23 @issue_keys ||= JiraIssueKeyExtractor.new(flag.description).issue_keys 24 end 25 26 def schema_version 27 '1.0' 28 end 29 30 def update_sequence_id 31 options[:update_sequence_id] || Client.generate_update_sequence_id 32 end 33 34 STRATEGY_NAMES = { 35 ::Operations::FeatureFlags::Strategy::STRATEGY_DEFAULT => 'All users', 36 ::Operations::FeatureFlags::Strategy::STRATEGY_GITLABUSERLIST => 'User List', 37 ::Operations::FeatureFlags::Strategy::STRATEGY_GRADUALROLLOUTUSERID => 'Percent of users', 38 ::Operations::FeatureFlags::Strategy::STRATEGY_FLEXIBLEROLLOUT => 'Percent rollout', 39 ::Operations::FeatureFlags::Strategy::STRATEGY_USERWITHID => 'User IDs' 40 }.freeze 41 42 private 43 44 # The summary does not map very well to our FeatureFlag model. 45 # 46 # We allow feature flags to have multiple strategies, depending 47 # on the environment. Jira expects a single rollout strategy. 48 # 49 # Also, we don't actually support showing a single flag, so we use the 50 # edit path as an interim solution. 51 def summary(strategies = flag.strategies) 52 { 53 url: edit_project_feature_flag_url(flag.project, flag), 54 lastUpdated: flag.updated_at.iso8601, 55 status: { 56 enabled: flag.active, 57 defaultValue: '', 58 rollout: { 59 percentage: strategies.map do |s| 60 s.parameters['rollout'] || s.parameters['percentage'] 61 end.compact.first&.to_f, 62 text: strategies.map { |s| STRATEGY_NAMES[s.name] }.compact.join(', ') 63 }.compact 64 } 65 } 66 end 67 68 def details 69 envs = flag.strategies.flat_map do |s| 70 s.scopes.map do |es| 71 env_type = es.environment_scope.scan(/development|testing|staging|production/).first 72 [es.environment_scope, env_type, s] 73 end 74 end 75 76 envs.map do |env_name, env_type, strat| 77 summary([strat]).merge(environment: { name: env_name, type: env_type }.compact) 78 end 79 end 80 end 81 end 82 end 83end 84