Allow to configure Flipper HTTP adapter with gitlab.yml

Details

GitLab Feature Flag now supports Flipper API. We extend Feature class to connect to the GitLab Feature Flag Server via HTTP adapter.

Proposal

  • Extend config file (gitlab.yml.example) to accept
    • feature_flags:flipper_http:enabled ... If the HTTP adapter is enabled or not.
    • feature_flags:flipper_http:url ... Feature Flag URL
    • feature_flags:flipper_http:instance_id ... Client instance ID
  • Extend Feature class to allow to initialize HTTP adapter with the new config values
  • Documentation
    • How it's architected
    • How to enable it
    • How to disable it
    • Troubleshooting

Adapter hierarchy

Example of config file

diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index bd328d9919a..75d2eb10188 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -541,6 +541,10 @@ production: &base
       # url: https://gitlab.com/api/v4/feature_flags/unleash/<project_id>
       # app_name: gitlab.com # Environment name of your GitLab instance
       # instance_id: INSTANCE_ID
+    flipper-http:
+      # enabled: false
+      # url: https://gitlab.com/api/v4/feature_flags/unleash/<project_id>
+      # instance_id: INSTANCE_ID
 
   #
   # 2. GitLab CI settings

Example of Flipper HTTP Adapter integration

diff --git a/lib/feature.rb b/lib/feature.rb
index d995e0a988f..e520b673102 100644
--- a/lib/feature.rb
+++ b/lib/feature.rb
@@ -153,14 +153,23 @@ class Feature
     end
 
     def build_flipper_instance
-      active_record_adapter = Flipper::Adapters::ActiveRecord.new(
-        feature_class: FlipperFeature,
-        gate_class: FlipperGate)
+      main_adapter =
+        if Gitlab.config.feature_flags.flipper.enabled
+          Flipper::Adapters::Http.new(
+            url: Gitlab.config.feature_flags.flipper.url,
+            headers: {
+                'instance_id' => Gitlab.config.feature_flags.flipper.instance_id
+            })
+        else
+          Flipper::Adapters::ActiveRecord.new(
+            feature_class: FlipperFeature,
+            gate_class: FlipperGate)
+        end
 
       # Redis L2 cache
       redis_cache_adapter =
         Flipper::Adapters::ActiveSupportCacheStore.new(
-          active_record_adapter,
+          main_adapter,
           l2_cache_backend,
           expires_in: 1.hour)

NOTES

  • We likely use HTTP adapter on dev.gitlab.org, staging.gitlab.com and gitlab.com instances only. The other instances (e.g. on-premises ones) likely keep using Database adapter.
  • As always, Feature class is the central place to control feature flags in GitLab.
  • This is a part of ~Dogfooding issues.
Edited by Shinya Maeda