Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeger-Jan van de Weg <git@zjvandeweg.nl>2018-05-02 22:41:47 +0300
committerZeger-Jan van de Weg <git@zjvandeweg.nl>2018-05-03 17:53:23 +0300
commita5736b72d58b4d4fa8f777bccc24e744e10f369b (patch)
treea6c7c2499a44fc2b0d5282497f3ee93234b6353c
parent764b039cb604794b15facc5c4a59ecd8dc590483 (diff)
Introduce small feature flag package
Feature flags on the Gitaly server weren't possible before and it was suggested in https://gitlab.com/gitlab-org/gitaly/issues/1170 that Gitaly could do this through gRPC metadata. This gives control on wether of not to execute new code paths to Rails, where the server needs to set a header in the form of `gitaly-feature-<flag_name>` to "true".
-rw-r--r--CHANGELOG.md5
-rw-r--r--internal/featureflag/grpc_header.go34
-rw-r--r--internal/featureflag/grpc_header_test.go31
3 files changed, 70 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 589720c3f..4a1a75bad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Gitaly changelog
+UNRELEASED
+
+- Introduce feature flag package based on gRPC metadata
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/704
+
v0.98.0
- Server implementation for repository raw_changes
diff --git a/internal/featureflag/grpc_header.go b/internal/featureflag/grpc_header.go
new file mode 100644
index 000000000..8d63fb41f
--- /dev/null
+++ b/internal/featureflag/grpc_header.go
@@ -0,0 +1,34 @@
+package featureflag
+
+import (
+ "fmt"
+
+ "golang.org/x/net/context"
+ "google.golang.org/grpc/metadata"
+)
+
+// IsEnabled checks if the feature flag is enabled for the passed context.
+// Only return true if the metadata for the feature flag is set to "true"
+func IsEnabled(ctx context.Context, flag string) bool {
+ if flag == "" {
+ return false
+ }
+
+ md, ok := metadata.FromIncomingContext(ctx)
+ if !ok {
+ return false
+ }
+
+ headerKey := fmt.Sprintf("gitaly-feature-%s", flag)
+ val, ok := md[headerKey]
+ if !ok {
+ return false
+ }
+
+ return len(val) > 0 && val[0] == "true"
+}
+
+// IsDisabled is the inverse operation of IsEnabled
+func IsDisabled(ctx context.Context, flag string) bool {
+ return !IsEnabled(ctx, flag)
+}
diff --git a/internal/featureflag/grpc_header_test.go b/internal/featureflag/grpc_header_test.go
new file mode 100644
index 000000000..76e0925c5
--- /dev/null
+++ b/internal/featureflag/grpc_header_test.go
@@ -0,0 +1,31 @@
+package featureflag
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc/metadata"
+)
+
+func TestGRPCMetadataFeatureFlag(t *testing.T) {
+ testCases := []struct {
+ flag string
+ headers map[string]string
+ enabled bool
+ }{
+ {"", nil, false},
+ {"flag", nil, false},
+ {"flag", map[string]string{"flag": "true"}, false},
+ {"flag", map[string]string{"gitaly-feature-flag": "TRUE"}, false},
+ {"flag", map[string]string{"gitaly-feature-flag": "true"}, true},
+ }
+
+ for _, tc := range testCases {
+ md := metadata.New(tc.headers)
+ ctx := metadata.NewIncomingContext(context.Background(), md)
+
+ assert.Equal(t, tc.enabled, IsEnabled(ctx, tc.flag))
+ assert.NotEqual(t, tc.enabled, IsDisabled(ctx, tc.flag))
+ }
+}