Skip to content

Feature flags MVC

Kamil Trzciński requested to merge feature-flags-backend into master

What does this MR do?

This introduces a simple Feature Flags backend as part of Operations.

This exposes Unleash compatible API that can be consumed by Unleash clients.

This is a minimal implementation that fulfils the above goal, and only allows to create/edit/destroy feature flags, and fetch them with clients.

Assumptions implemented

  1. This introduces a new DB model: Operations::FeatureFlags tied to project to have a list of all features, and enabled/disabled,
  2. This introduces a new DB model: Operations::FeatureFlagsAccessToken to provide an interface to be able to create additional access token to use feature flags by clients. Currently, we implicitly always create single access token when presented form,
  3. This only allows enabling/disable FF,
  4. This create separate scope for client APIs (consumed by Unleash) /api/v4/feature_flags/projects/:id/unleash/.... The idea behind doing that via /api/v4/feature_flags/ is that this endpoint can later be served under separate domain doing simple forward proxy. The User API will have to be put in /api/v4/projects/:id/feature_flags/:ff_id,
  5. This requires us to securely store access token (there is separate MR for that purpose), it will be integrated once done,
  6. Features-as-a-code (https://gitlab.com/gitlab-org/gitlab-ee/issues/6220#note_93521369) can be freely implemented on top of that, and this approach does not deny that,
  7. We do not track usage of feature flags yet, this is MVC. There's a long discussion in https://gitlab.com/gitlab-org/gitlab-ee/issues/6220,
  8. This implementation is made in mind that Unleash is just a provider, that can be changed to something more suitable once we identify that.

Further improvements

  1. Use Object Storage to preserve configurations,
  2. Keep tracking of features being used (metrics?),
  3. Use features-as-a-code: https://gitlab.com/gitlab-org/gitlab-ee/issues/6220#note_93521369,
  4. Tie features with environments, keep track what environments use what flags.

Usage

  1. Go to Operations > Feature Flags,
  2. Click add New Feature Flag,
  3. Fill the name of the feature flag (can contain only lowercase letters, digits, '_' and '-'. Must start with a letter, and cannot end with '-' or '_'"),
  4. Save,
  5. Click configure to get access credentials,
  6. Put the credentials in your application.

Simple application making use of credentials

package main

import (
    "io"
    "log"
    "net/http"

    "github.com/Unleash/unleash-client-go"
)

type metricsInterface struct {
}

func init() {
    unleash.Initialize(
        unleash.WithUrl("http://localhost:3000/api/v4/feature_flags/projects/14/unleash"),
        unleash.WithInstanceId("29QmjsW6KngPR5JNPMWx"),
        unleash.WithAppName("production"),
        // This is due to bug with Unleash and sync call and being broken ;)
        unleash.WithListener(&metricsInterface{}),
    )
}

func helloServer(w http.ResponseWriter, req *http.Request) {
    if unleash.IsEnabled("my_feature_name") {
        io.WriteString(w, "Feature enabled\n")
    } else {
        io.WriteString(w, "hello, world!\n")
    }
}

func main() {
    http.HandleFunc("/", helloServer)
    log.Fatal(http.ListenAndServe(":12345", nil))
}

The meaning of Configure fields

  • API URL: where client has to connect to get a list of feature flags,
  • Instance ID: the unique token that identifies project and allows us to authorize the operation of getting feature flag,
  • App name: this should be user-provided content, ideally I (@ayufan) think that it should be Environment Name, thus $CI_ENVIRONMENT_SLUG. This might give us an option later to provide different configuration sets for different environments, based on user preference.

Screenshots

See https://gitlab.com/gitlab-org/gitlab-ee/issues/6220 for latest mockups. The below represent the current screenshots from development:

Screen_Shot_2018-09-18_at_14.29.33

Screen_Shot_2018-09-18_at_14.29.25

image

Screen_Shot_2018-09-18_at_14.30.20

Screen_Shot_2018-09-18_at_16.00.58

Does this MR meet the acceptance criteria?

What are the relevant issue numbers?

https://gitlab.com/gitlab-org/gitlab-ee/issues/6220

Edited by 🤖 GitLab Bot 🤖

Merge request reports