diff --git a/build/main.go b/build/main.go index e7fbd84f9a..bf37a6255d 100644 --- a/build/main.go +++ b/build/main.go @@ -48,7 +48,7 @@ func (f *Flipt) Base(ctx context.Context, source *dagger.Directory) (*Container, return f.BaseContainer, err } -// Return container with Flipt binariesin a thinner alpine distribution +// Return container with Flipt binaries in a thinner alpine distribution func (f *Flipt) Build(ctx context.Context, source *dagger.Directory) (*Container, error) { base, err := f.Base(ctx, source) if err != nil { diff --git a/build/testing/cli.go b/build/testing/cli.go index 98856bd0bc..37a22e163f 100644 --- a/build/testing/cli.go +++ b/build/testing/cli.go @@ -457,7 +457,7 @@ segments: value: buzz ` - expectedYAMLStreamOutput = `version: "1.2" + expectedYAMLStreamOutput = `version: "1.3" namespace: default --- namespace: foo diff --git a/build/testing/integration.go b/build/testing/integration.go index 5c82911eb3..977bf9a56f 100644 --- a/build/testing/integration.go +++ b/build/testing/integration.go @@ -226,7 +226,7 @@ func Integration(ctx context.Context, client *dagger.Client, base, flipt *dagger name := strings.ToLower(replacer.Replace(fmt.Sprintf("flipt-test-%s-config-%s", caseName, config.name))) flipt = flipt. WithEnvVariable("CI", os.Getenv("CI")). - WithEnvVariable("FLIPT_LOG_LEVEL", "debug"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithExposedPort(config.port) if exportLogs { @@ -344,7 +344,7 @@ func withCockroach(fn testCaseFn) testCaseFn { func cache(ctx context.Context, _ *dagger.Client, base, flipt *dagger.Container, conf testConfig) func() error { flipt = flipt. - WithEnvVariable("FLIPT_LOG_LEVEL", "DEBUG"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("FLIPT_CACHE_ENABLED", "true"). WithEnvVariable("FLIPT_CACHE_TTL", "1s") @@ -369,7 +369,7 @@ func cacheWithTLS(ctx context.Context, client *dagger.Client, base, flipt *dagge AsService() flipt = flipt. - WithEnvVariable("FLIPT_LOG_LEVEL", "DEBUG"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("FLIPT_CACHE_ENABLED", "true"). WithEnvVariable("FLIPT_CACHE_TTL", "1s"). WithEnvVariable("FLIPT_CACHE_BACKEND", "redis"). @@ -389,7 +389,7 @@ const ( func local(ctx context.Context, client *dagger.Client, base, flipt *dagger.Container, conf testConfig) func() error { flipt = flipt. WithDirectory("/tmp/testdata", base.Directory(singleRevisionTestdataDir)). - WithEnvVariable("FLIPT_LOG_LEVEL", "DEBUG"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("FLIPT_STORAGE_TYPE", "local"). WithEnvVariable("FLIPT_STORAGE_LOCAL_PATH", "/tmp/testdata"). WithEnvVariable("UNIQUE", uuid.New().String()) @@ -454,7 +454,7 @@ func git(ctx context.Context, client *dagger.Client, base, flipt *dagger.Contain flipt = flipt. WithServiceBinding("gitea", gitea.AsService()). - WithEnvVariable("FLIPT_LOG_LEVEL", "DEBUG"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("FLIPT_STORAGE_TYPE", "git"). WithEnvVariable("FLIPT_STORAGE_GIT_REPOSITORY", "http://gitea:3000/root/features.git"). WithEnvVariable("FLIPT_STORAGE_GIT_AUTHENTICATION_BASIC_USERNAME", "root"). @@ -490,7 +490,7 @@ func s3(ctx context.Context, client *dagger.Client, base, flipt *dagger.Containe flipt = flipt. WithServiceBinding("minio", minio). - WithEnvVariable("FLIPT_LOG_LEVEL", "DEBUG"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("AWS_ACCESS_KEY_ID", "user"). WithEnvVariable("AWS_SECRET_ACCESS_KEY", "password"). WithEnvVariable("FLIPT_STORAGE_TYPE", "object"). @@ -554,7 +554,7 @@ func oci(ctx context.Context, client *dagger.Client, base, flipt *dagger.Contain flipt = flipt. WithServiceBinding("zot", zot.AsService()). - WithEnvVariable("FLIPT_LOG_LEVEL", "DEBUG"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("FLIPT_STORAGE_TYPE", "oci"). WithEnvVariable("FLIPT_STORAGE_OCI_REPOSITORY", "http://zot:5000/readonly:latest"). WithEnvVariable("FLIPT_STORAGE_OCI_AUTHENTICATION_USERNAME", "username"). @@ -619,7 +619,7 @@ func importExport(ctx context.Context, _ *dagger.Client, base, flipt *dagger.Con if ns == "default" { // replace namespace in expected yaml - expected = strings.ReplaceAll(expected, "version: \"1.2\"\n", fmt.Sprintf("version: \"1.2\"\nnamespace: %s\n", ns)) + expected = strings.ReplaceAll(expected, "version: \"1.3\"\n", fmt.Sprintf("version: \"1.3\"\nnamespace: %s\n", ns)) } if ns != "default" { @@ -870,7 +870,7 @@ func azblob(ctx context.Context, client *dagger.Client, base, flipt *dagger.Cont flipt = flipt. WithServiceBinding("azurite", azurite). - WithEnvVariable("FLIPT_LOG_LEVEL", "DEBUG"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("FLIPT_STORAGE_TYPE", "object"). WithEnvVariable("FLIPT_STORAGE_OBJECT_TYPE", "azblob"). WithEnvVariable("FLIPT_STORAGE_OBJECT_AZBLOB_ENDPOINT", "http://azurite:10000/devstoreaccount1"). @@ -902,7 +902,7 @@ func gcs(ctx context.Context, client *dagger.Client, base, flipt *dagger.Contain flipt = flipt. WithServiceBinding("gcs", gcs). - WithEnvVariable("FLIPT_LOG_LEVEL", "DEBUG"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("FLIPT_STORAGE_TYPE", "object"). WithEnvVariable("FLIPT_STORAGE_OBJECT_TYPE", "googlecloud"). WithEnvVariable("FLIPT_STORAGE_OBJECT_GOOGLECLOUD_BUCKET", "testdata"). @@ -1014,7 +1014,7 @@ func serveOIDC(_ context.Context, _ *dagger.Client, base, flipt *dagger.Containe }) return flipt. - WithEnvVariable("FLIPT_LOG_LEVEL", "debug"). + WithEnvVariable("FLIPT_LOG_LEVEL", "WARN"). WithEnvVariable("FLIPT_AUTHENTICATION_METHODS_KUBERNETES_DISCOVERY_URL", "https://discover.svc"). WithServiceBinding("discover.svc", base. WithNewFile("/server.crt", dagger.ContainerWithNewFileOpts{ diff --git a/build/testing/integration/api/api.go b/build/testing/integration/api/api.go index 2f07435b3a..a02ca025a8 100644 --- a/build/testing/integration/api/api.go +++ b/build/testing/integration/api/api.go @@ -192,7 +192,7 @@ func API(t *testing.T, ctx context.Context, opts integration.TestOpts) { assert.Equal(t, "Test 2", updated.Name) - t.Log("List all Flags error with invalid page token") + t.Log("List all flags error with invalid page token") _, err = client.Flipt().ListFlags(ctx, &flipt.ListFlagRequest{ NamespaceKey: namespace.Key, @@ -259,6 +259,29 @@ func API(t *testing.T, ctx context.Context, opts integration.TestOpts) { assert.Equal(t, "one", updatedVariant.Key) assert.Equal(t, "One", updatedVariant.Name) + + t.Log("Set default variant for flag \"test\".") + + _, err = client.Flipt().UpdateFlag(ctx, &flipt.UpdateFlagRequest{ + NamespaceKey: namespace.Key, + Key: enabled.Key, + Name: "Test 2", + Description: enabled.Description, + Enabled: true, + DefaultVariantId: updatedVariant.Id, + }) + + require.NoError(t, err) + + flag, err = client.Flipt().GetFlag(ctx, &flipt.GetFlagRequest{ + NamespaceKey: namespace.Key, + Key: enabled.Key, + }) + + require.NoError(t, err) + assert.Equal(t, updatedVariant.Id, flag.DefaultVariant.Id) + assert.Equal(t, updatedVariant.Key, flag.DefaultVariant.Key) + assert.Equal(t, updatedVariant.Name, flag.DefaultVariant.Name) }) t.Run("Segments and Constraints", func(t *testing.T) { diff --git a/build/testing/integration/readonly/testdata/main/default.yaml b/build/testing/integration/readonly/testdata/main/default.yaml index 064b6c5670..ad6c48ae14 100644 --- a/build/testing/integration/readonly/testdata/main/default.yaml +++ b/build/testing/integration/readonly/testdata/main/default.yaml @@ -1,4 +1,4 @@ -version: "1.2" +version: "1.3" flags: - key: flag_001 name: FLAG_001 diff --git a/build/testing/integration/readonly/testdata/main/production.yaml b/build/testing/integration/readonly/testdata/main/production.yaml index 225d63e9f7..83a044dbc7 100644 --- a/build/testing/integration/readonly/testdata/main/production.yaml +++ b/build/testing/integration/readonly/testdata/main/production.yaml @@ -1,4 +1,4 @@ -version: "1.2" +version: "1.3" namespace: production flags: - key: flag_001 diff --git a/config/migrations/cockroachdb/11_default_variant.up.sql b/config/migrations/cockroachdb/11_default_variant.up.sql new file mode 100644 index 0000000000..1f6ac9c5b5 --- /dev/null +++ b/config/migrations/cockroachdb/11_default_variant.up.sql @@ -0,0 +1 @@ +ALTER TABLE flags ADD COLUMN default_variant_id VARCHAR(255) REFERENCES variants(id) ON DELETE SET NULL; \ No newline at end of file diff --git a/config/migrations/mysql/13_default_variant.up.sql b/config/migrations/mysql/13_default_variant.up.sql new file mode 100644 index 0000000000..a99b270954 --- /dev/null +++ b/config/migrations/mysql/13_default_variant.up.sql @@ -0,0 +1 @@ +ALTER TABLE `flags` ADD COLUMN `default_variant_id` VARCHAR(255) REFERENCES variants(`id`) ON DELETE SET NULL; \ No newline at end of file diff --git a/config/migrations/postgres/14_default_variant.up.sql b/config/migrations/postgres/14_default_variant.up.sql new file mode 100644 index 0000000000..1f6ac9c5b5 --- /dev/null +++ b/config/migrations/postgres/14_default_variant.up.sql @@ -0,0 +1 @@ +ALTER TABLE flags ADD COLUMN default_variant_id VARCHAR(255) REFERENCES variants(id) ON DELETE SET NULL; \ No newline at end of file diff --git a/config/migrations/sqlite3/13_default_variant.up.sql b/config/migrations/sqlite3/13_default_variant.up.sql new file mode 100644 index 0000000000..a99b270954 --- /dev/null +++ b/config/migrations/sqlite3/13_default_variant.up.sql @@ -0,0 +1 @@ +ALTER TABLE `flags` ADD COLUMN `default_variant_id` VARCHAR(255) REFERENCES variants(`id`) ON DELETE SET NULL; \ No newline at end of file diff --git a/core/validation/flipt.cue b/core/validation/flipt.cue index 11f982a097..939af1ba9b 100644 --- a/core/validation/flipt.cue +++ b/core/validation/flipt.cue @@ -1,19 +1,19 @@ +version: "1.0" | "1.1" | "1.2" | *"1.3" + close({ - version: "1.0" | "1.1" | *"1.2" namespace: string & =~"^[-_,A-Za-z0-9]+$" | *"default" - flags: [...{_version: version} & #Flag] + flags: [...#Flag] segments: [...#Segment] }) #Flag: { - _version: string key: string & =~"^[-_,A-Za-z0-9]+$" name: string & =~"^.+$" description?: string enabled: bool | *false variants: [...#Variant] rules: [...#Rule] - if _version == "1.1" || _version == "1.2" { + if version == "1.1" || version == "1.2" || version == "1.3" { type: "BOOLEAN_FLAG_TYPE" | *"VARIANT_FLAG_TYPE" #FlagBoolean | *{} } @@ -32,6 +32,9 @@ close({ name?: string & =~"^.+$" description?: string attachment: {...} | [...] | *null + if version == "1.3" { + default: bool | *false + } } #RuleSegment: { diff --git a/core/validation/flipt.json b/core/validation/flipt.json index 089c4261d3..7e6d90f5da 100644 --- a/core/validation/flipt.json +++ b/core/validation/flipt.json @@ -13,14 +13,10 @@ }, "oneOf": [ { - "required": [ - "segment" - ] + "required": ["segment"] }, { - "required": [ - "threshold" - ] + "required": ["threshold"] } ] }, @@ -39,37 +35,24 @@ } }, "operator": { - "enum": [ - "AND_SEGMENT_OPERATOR", - "OR_SEGMENT_OPERATOR" - ] + "enum": ["AND_SEGMENT_OPERATOR", "OR_SEGMENT_OPERATOR"] }, "value": { "type": "boolean" } }, - "required": [ - "value" - ], + "required": ["value"], "oneOf": [ { - "required": [ - "key" - ], + "required": ["key"], "not": { - "required": [ - "keys" - ] + "required": ["keys"] } }, { - "required": [ - "keys" - ], + "required": ["keys"], "not": { - "required": [ - "key" - ] + "required": ["key"] } } ] @@ -84,15 +67,10 @@ "type": "boolean" } }, - "required": [ - "percentage", - "value" - ] + "required": ["percentage", "value"] }, "rule": { - "required": [ - "segment" - ], + "required": ["segment"], "properties": { "segment": { "type": "string", @@ -102,10 +80,7 @@ "type": "array", "uniqueItems": true, "items": { - "required": [ - "variant", - "rollout" - ], + "required": ["variant", "rollout"], "properties": { "variant": { "type": "string" @@ -121,9 +96,7 @@ } }, "variant": { - "required": [ - "key" - ], + "required": ["key"], "properties": { "key": { "type": "string" @@ -134,6 +107,9 @@ "description": { "type": "string" }, + "default": { + "type": "boolean" + }, "attachment": { "oneOf": [ { @@ -153,9 +129,7 @@ "const": "STRING_COMPARISON_TYPE" } }, - "required": [ - "operator" - ] + "required": ["operator"] }, "then": { "properties": { @@ -181,9 +155,7 @@ "const": "NUMBER_COMPARISON_TYPE" } }, - "required": [ - "operator" - ] + "required": ["operator"] }, "then": { "properties": { @@ -211,19 +183,12 @@ "const": "BOOLEAN_COMPARISON_TYPE" } }, - "required": [ - "operator" - ] + "required": ["operator"] }, "then": { "properties": { "operator": { - "enum": [ - "true", - "false", - "present", - "notpresent" - ] + "enum": ["true", "false", "present", "notpresent"] } } } @@ -235,9 +200,7 @@ "const": "DATETIME_COMPARISON_TYPE" } }, - "required": [ - "operator" - ] + "required": ["operator"] }, "then": { "properties": { @@ -263,29 +226,18 @@ "const": "ENTITY_ID_COMPARISON_TYPE" } }, - "required": [ - "operator" - ] + "required": ["operator"] }, "then": { "properties": { "operator": { - "enum": [ - "eq", - "neq", - "isoneof", - "isnotoneof" - ] + "enum": ["eq", "neq", "isoneof", "isnotoneof"] } } } }, "constraint": { - "required": [ - "type", - "property", - "operator" - ], + "required": ["type", "property", "operator"], "properties": { "type": { "enum": [ @@ -339,12 +291,7 @@ "type": "array", "uniqueItems": true, "items": { - "required": [ - "key", - "name", - "type", - "enabled" - ], + "required": ["key", "name", "type", "enabled"], "properties": { "key": { "type": "string", @@ -355,10 +302,7 @@ "pattern": "^.+$" }, "type": { - "enum": [ - "VARIANT_FLAG_TYPE", - "BOOLEAN_FLAG_TYPE" - ] + "enum": ["VARIANT_FLAG_TYPE", "BOOLEAN_FLAG_TYPE"] }, "description": { "type": "string" @@ -399,9 +343,7 @@ }, "then": { "not": { - "required": [ - "rollouts" - ] + "required": ["rollouts"] } } }, @@ -415,9 +357,7 @@ }, "then": { "not": { - "required": [ - "rules" - ] + "required": ["rules"] } } }, @@ -431,9 +371,7 @@ }, "then": { "not": { - "required": [ - "variants" - ] + "required": ["variants"] } } } @@ -444,11 +382,7 @@ "type": "array", "uniqueItems": true, "items": { - "required": [ - "key", - "name", - "match_type" - ], + "required": ["key", "name", "match_type"], "properties": { "key": { "type": "string", @@ -468,19 +402,11 @@ } }, "match_type": { - "enum": [ - "ALL_MATCH_TYPE", - "ANY_MATCH_TYPE" - ] + "enum": ["ALL_MATCH_TYPE", "ANY_MATCH_TYPE"] } } } } }, - "required": [ - "version", - "namespace", - "flags", - "segments" - ] -} \ No newline at end of file + "required": ["version", "namespace", "flags", "segments"] +} diff --git a/core/validation/testdata/valid_default_variant_v3.yaml b/core/validation/testdata/valid_default_variant_v3.yaml new file mode 100644 index 0000000000..598b358420 --- /dev/null +++ b/core/validation/testdata/valid_default_variant_v3.yaml @@ -0,0 +1,36 @@ +version: "1.3" +namespace: default +flags: +- key: flipt + name: flipt + description: flipt + enabled: false + variants: + - key: flipt + name: flipt + - key: flipt + name: flipt + default: true + rules: + - segment: internal-users + distributions: + - variant: fromFlipt + rollout: 100 + - segment: all-users + distributions: + - variant: fromFlipt2 + rollout: 100 +segments: +- key: all-users + name: All Users + description: All Users + match_type: ALL_MATCH_TYPE +- key: internal-users + name: Internal Users + description: All internal users at flipt. + constraints: + - type: STRING_COMPARISON_TYPE + property: organization + operator: eq + value: flipt + match_type: ALL_MATCH_TYPE diff --git a/core/validation/validate_test.go b/core/validation/validate_test.go index 729e06e940..360c638b5a 100644 --- a/core/validation/validate_test.go +++ b/core/validation/validate_test.go @@ -10,7 +10,8 @@ import ( ) func TestValidate_V1_Success(t *testing.T) { - f, err := os.Open("testdata/valid_v1.yaml") + const file = "testdata/valid_v1.yaml" + f, err := os.Open(file) require.NoError(t, err) defer f.Close() @@ -18,12 +19,13 @@ func TestValidate_V1_Success(t *testing.T) { v, err := NewFeaturesValidator() require.NoError(t, err) - err = v.Validate("testdata/valid_v1.yaml", f) + err = v.Validate(file, f) assert.NoError(t, err) } func TestValidate_Latest_Success(t *testing.T) { - f, err := os.Open("testdata/valid.yaml") + const file = "testdata/valid.yaml" + f, err := os.Open(file) require.NoError(t, err) defer f.Close() @@ -31,12 +33,13 @@ func TestValidate_Latest_Success(t *testing.T) { v, err := NewFeaturesValidator() require.NoError(t, err) - err = v.Validate("testdata/valid.yaml", f) + err = v.Validate(file, f) assert.NoError(t, err) } -func TestValidate_Latest_Segments_V2(t *testing.T) { - f, err := os.Open("testdata/valid_segments_v2.yaml") +func TestValidate_Segments_V2(t *testing.T) { + const file = "testdata/valid_segments_v2.yaml" + f, err := os.Open(file) require.NoError(t, err) defer f.Close() @@ -44,12 +47,27 @@ func TestValidate_Latest_Segments_V2(t *testing.T) { v, err := NewFeaturesValidator() require.NoError(t, err) - err = v.Validate("testdata/valid_segments_v2.yaml", f) + err = v.Validate(file, f) + assert.NoError(t, err) +} + +func TestValidate_DefaultVariant_V3(t *testing.T) { + const file = "testdata/valid_default_variant_v3.yaml" + f, err := os.Open(file) + require.NoError(t, err) + + defer f.Close() + + v, err := NewFeaturesValidator() + require.NoError(t, err) + + err = v.Validate(file, f) assert.NoError(t, err) } func TestValidate_YAML_Stream(t *testing.T) { - f, err := os.Open("testdata/valid_yaml_stream.yaml") + const file = "testdata/valid_yaml_stream.yaml" + f, err := os.Open(file) require.NoError(t, err) defer f.Close() @@ -57,12 +75,13 @@ func TestValidate_YAML_Stream(t *testing.T) { v, err := NewFeaturesValidator() require.NoError(t, err) - err = v.Validate("testdata/valid_yaml_stream.yaml", f) + err = v.Validate(file, f) assert.NoError(t, err) } func TestValidate_Failure(t *testing.T) { - f, err := os.Open("testdata/invalid.yaml") + const file = "testdata/invalid.yaml" + f, err := os.Open(file) require.NoError(t, err) defer f.Close() @@ -70,7 +89,7 @@ func TestValidate_Failure(t *testing.T) { v, err := NewFeaturesValidator() require.NoError(t, err) - err = v.Validate("testdata/invalid.yaml", f) + err = v.Validate(file, f) errs, ok := Unwrap(err) require.True(t, ok) @@ -79,12 +98,13 @@ func TestValidate_Failure(t *testing.T) { require.True(t, errors.As(errs[0], &ferr)) assert.Equal(t, "flags.0.rules.1.distributions.0.rollout: invalid value 110 (out of bound <=100)", ferr.Message) - assert.Equal(t, "testdata/invalid.yaml", ferr.Location.File) + assert.Equal(t, file, ferr.Location.File) assert.Equal(t, 22, ferr.Location.Line) } func TestValidate_Failure_YAML_Stream(t *testing.T) { - f, err := os.Open("testdata/invalid_yaml_stream.yaml") + const file = "testdata/invalid_yaml_stream.yaml" + f, err := os.Open(file) require.NoError(t, err) defer f.Close() @@ -92,7 +112,7 @@ func TestValidate_Failure_YAML_Stream(t *testing.T) { v, err := NewFeaturesValidator() require.NoError(t, err) - err = v.Validate("testdata/invalid_yaml_stream.yaml", f) + err = v.Validate(file, f) errs, ok := Unwrap(err) require.True(t, ok) @@ -101,12 +121,13 @@ func TestValidate_Failure_YAML_Stream(t *testing.T) { require.True(t, errors.As(errs[0], &ferr)) assert.Equal(t, "flags.0.rules.1.distributions.0.rollout: invalid value 110 (out of bound <=100)", ferr.Message) - assert.Equal(t, "testdata/invalid_yaml_stream.yaml", ferr.Location.File) + assert.Equal(t, file, ferr.Location.File) assert.Equal(t, 59, ferr.Location.Line) } func TestValidate_Extended(t *testing.T) { - f, err := os.Open("testdata/valid.yaml") + const file = "testdata/valid.yaml" + f, err := os.Open(file) require.NoError(t, err) defer f.Close() @@ -117,7 +138,7 @@ func TestValidate_Extended(t *testing.T) { v, err := NewFeaturesValidator(WithSchemaExtension(extended)) require.NoError(t, err) - err = v.Validate("testdata/valid.yaml", f) + err = v.Validate(file, f) errs, ok := Unwrap(err) require.True(t, ok) @@ -126,7 +147,7 @@ func TestValidate_Extended(t *testing.T) { require.True(t, errors.As(errs[0], &ferr)) assert.Equal(t, `flags.1.description: incomplete value =~"^.+$"`, ferr.Message) - assert.Equal(t, "testdata/valid.yaml", ferr.Location.File) + assert.Equal(t, file, ferr.Location.File) // location of the start of the boolean flag // which lacks a description assert.Equal(t, 30, ferr.Location.Line) diff --git a/go.work.sum b/go.work.sum index 12cf7af4e1..250bef50cb 100644 --- a/go.work.sum +++ b/go.work.sum @@ -24,6 +24,7 @@ cloud.google.com/go/channel v1.17.6/go.mod h1:fr0Oidb2mPfA0RNcV+JMSBv5rjpLHjy9zV cloud.google.com/go/cloudbuild v1.16.0/go.mod h1:CCWnqxLxEdh8kpOK83s3HTNBTpoIFn/U9j8DehlUyyA= cloud.google.com/go/clouddms v1.7.5/go.mod h1:O4GVvxKPxbXlVfxkoUIXi8UAwwIHoszYm32dJ8tgbvE= cloud.google.com/go/cloudtasks v1.12.7/go.mod h1:I6o/ggPK/RvvokBuUppsbmm4hrGouzFbf6fShIm0Pqc= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= @@ -138,16 +139,20 @@ github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0/go.mod h1:Pu5Zksi2 github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1/go.mod h1:9V2j0jn9jDEkCkv8w/bKTNppX/d0FVA1ud77xCIP4KA= github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.6.1/go.mod h1:xNjFERdhyMqZncbNJSPBsTCddk5kwsUVUzELQPMj/LA= github.com/Azure/go-amqp v1.0.5/go.mod h1:vZAogwdrkbyK3Mla8m/CxSc/aKdnTZ4IbPxl51Y5WZE= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest/autorest/adal v0.9.16/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/GoogleCloudPlatform/cloudsql-proxy v1.34.0/go.mod h1:XNDFTVaBS0jJYam3A88dpdzImNh0RRhBF4k05CNEENs= github.com/IBM/sarama v1.43.1/go.mod h1:GG5q1RURtDNPz8xxJs3mgX6Ytak8Z9eLhAkJPObe2xE= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/Microsoft/cosesign1go v1.1.0/go.mod h1:o+sw7nhlGE6twhfjXQDWmBJO8zmfQXEmCcXEi3zha8I= github.com/Microsoft/didx509go v0.0.2/go.mod h1:F+msvNlKCEm3RgUE3kRpi7E+6hdR6r5PtOLWQKYfGbs= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk= github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/actgardner/gogen-avro/v10 v10.2.1/go.mod h1:QUhjeHPchheYmMDni/Nx7VB0RsT/ee8YIgGY/xpEQgQ= @@ -173,8 +178,11 @@ github.com/aws/aws-sdk-go-v2 v1.27.2/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7 github.com/aws/aws-sdk-go-v2 v1.30.1/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2/go.mod h1:lPprDr1e6cJdyYeGXnRaJoP4Md+cDBvi2eOj00BlGmg= github.com/aws/aws-sdk-go-v2/config v1.27.17/go.mod h1:MzM3balLZeaafYcPz8IihAmam/aCz6niPQI0FdprxW0= +github.com/aws/aws-sdk-go-v2/config v1.27.23/go.mod h1:WMMYHqLCFu5LH05mFOF5tsq1PGEMfKbu083VKqLCd0o= github.com/aws/aws-sdk-go-v2/credentials v1.17.17/go.mod h1:e4khg9iY08LnFK/HXQDWMf9GDaiMari7jWPnXvKAuBU= +github.com/aws/aws-sdk-go-v2/credentials v1.17.23/go.mod h1:V/DvSURn6kKgcuKEk4qwSwb/fZ2d++FFARtWSbXnLqY= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.4/go.mod h1:Wjn5O9eS7uSi7vlPKt/v0MLTncANn9EMmoDvnzJli6o= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9/go.mod h1:CZBXGLaJnEZI6EVNcPd7a6B5IC5cA/GkRWtu9fp3S6Y= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13/go.mod h1:+rdA6ZLpaSeM7tSg/B0IEDinCIBJGmW8rKDFkYpP04g= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9/go.mod h1:5jJcHuwDagxN+ErjQ3PU3ocf6Ylc/p9x+BLO/+X4iXw= @@ -183,6 +191,7 @@ github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.8/go.mod h1:hD5YwHLOy6k7d6kqcn3me github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.10/go.mod h1:/WNsBOlKWZCG3PMh2aSp8vkyyT/clpMZqOtrnIKqGfk= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.10/go.mod h1:gYVF3nM1ApfTRDj9pvdhootBb8WbiIejuqn4w8ruMes= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15/go.mod h1:9xWJ3Q/S6Ojusz1UIkfycgD1mGirJfLLKqq3LPT7WN8= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.8/go.mod h1:yUQPRlWqGG0lfNsmjbRWKVwgilfBtZTOFSLEYALlAig= github.com/aws/aws-sdk-go-v2/service/kms v1.29.2/go.mod h1:elLDaj+1RNl9Ovn3dB6dWLVo5WQ+VLSUMKegl7N96fY= github.com/aws/aws-sdk-go-v2/service/s3 v1.54.4/go.mod h1:oSkRFuHVWmUY4Ssk16ErGzBqvYEbvORJFzFXzWhTB2s= @@ -191,8 +200,11 @@ github.com/aws/aws-sdk-go-v2/service/sns v1.29.2/go.mod h1:ZIs7/BaYel9NODoYa8PW3 github.com/aws/aws-sdk-go-v2/service/sqs v1.31.2/go.mod h1:J3XhTE+VsY1jDsdDY+ACFAppZj/gpvygzC5JE0bTLbQ= github.com/aws/aws-sdk-go-v2/service/ssm v1.49.2/go.mod h1:loBAHYxz7JyucJvq4xuW9vunu8iCzjNYfSrQg2QEczA= github.com/aws/aws-sdk-go-v2/service/sso v1.20.10/go.mod h1:5XKooCTi9VB/xZmJDvh7uZ+v3uQ7QdX6diOyhvPA+/w= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.4/go.mod h1:MZ/PVYU/mRbmSF6WK3ybCYHjA2mig8utVokDEVLDgE0= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4= github.com/aws/aws-sdk-go-v2/service/sts v1.28.11/go.mod h1:QXnthRM35zI92048MMwfFChjFmoufTdhtHmouwNfhhU= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ= github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/perks v0.0.0-20230307044200-03f9df79da1e/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q= @@ -248,6 +260,7 @@ github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDX github.com/containerd/imgcrypt v1.1.8/go.mod h1:x6QvFIkMyO2qGIY2zXc88ivEzcbgvLdWjoZyGqDap5U= github.com/containerd/nri v0.6.1/go.mod h1:7+sX3wNx+LR7RzhjnJiUkFDhn18P5Bg/0VnJ/uXpRJM= github.com/containerd/protobuild v0.3.0/go.mod h1:5mNMFKKAwCIAkFBPiOdtRx2KiQlyEJeMXnL5R1DsWu8= +github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= github.com/containerd/ttrpc v1.2.4/go.mod h1:ojvb8SJBSch0XkqNO0L0YX/5NxR3UnVk2LzFKBK0upc= github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= @@ -258,6 +271,7 @@ github.com/containers/ocicrypt v1.1.10/go.mod h1:YfzSSr06PTHQwSTUKqDSjish9BeW1E4 github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= @@ -268,6 +282,11 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUn github.com/dgryski/go-gk v0.0.0-20200319235926-a69029f61654/go.mod h1:qm+vckxRlDt0aOla0RYJJVeqHZlWfOm2UIxHaqPB46E= github.com/dmarkham/enumer v1.5.9/go.mod h1:e4VILe2b1nYK3JKJpRmNdl5xbDQvELc6tQ8b+GsGk6E= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= @@ -288,6 +307,7 @@ github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQL github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/fsouza/fake-gcs-server v1.17.0/go.mod h1:D1rTE4YCyHFNa99oyJJ5HyclvN/0uQR+pM/VdlL83bw= @@ -385,6 +405,7 @@ github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3t github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -399,6 +420,7 @@ github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmt github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= +github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/markbates/pkger v0.15.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/matryer/moq v0.3.4/go.mod h1:wqm9QObyoMuUtH81zFfs3EK6mXEcByy+TjvSROOXJ2U= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -430,10 +452,10 @@ github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGp github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mutecomm/go-sqlcipher/v4 v4.4.0/go.mod h1:PyN04SaWalavxRGH9E8ZftG6Ju7rsPrGmQRjrEaVpiY= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= @@ -444,6 +466,7 @@ github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDm github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neo4j/neo4j-go-driver v1.8.1-0.20200803113522-b626aa943eba/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI= @@ -472,6 +495,7 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qq github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls= github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96/go.mod h1:90HvCY7+oHHUKkbeMCiHt1WuFR2/hPJ9QrljDG+v6ls= github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rqlite/gorqlite v0.0.0-20230708021416-2acd02b70b79/go.mod h1:xF/KoXmrRyahPfo5L7Szb5cAAUl53dMWBh9cMruGEZg= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= @@ -483,20 +507,26 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/snowflakedb/gosnowflake v1.6.19/go.mod h1:FM1+PWUdwB9udFDsXdfD58NONC0m+MlOSmQRvimobSM= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M= github.com/streadway/quantile v0.0.0-20220407130108-4246515d968d/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A= github.com/tsenart/vegeta v12.7.0+incompatible/go.mod h1:Smz/ZWfhKRcyDDChZkG3CyTHdj87lHzio/HOCkbndXM= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= +github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/veraison/go-cose v1.2.0/go.mod h1:7ziE85vSq4ScFTg6wyoMXjucIGOf4JkFEZi/an96Ct4= github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= @@ -548,34 +578,46 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= @@ -585,6 +627,7 @@ google.golang.org/api v0.170.0/go.mod h1:/xql9M2btF85xac/VAm4PsLMTLVGUOpq4BE9R8j google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/api v0.176.1/go.mod h1:j2MaSDYcvYV1lkZ1+SMW4IeF90SrEyFA+tluDYWRrFg= google.golang.org/api v0.177.0/go.mod h1:srbhue4MLjkjbkux5p3dw/ocYOSZTaIEvf7bCOnFQDw= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= @@ -610,9 +653,11 @@ google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= k8s.io/apiserver v0.26.2/go.mod h1:GHcozwXgXsPuOJ28EnQ/jXEM9QeG6HT22YxSNmpYNh8= k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= diff --git a/internal/ext/common.go b/internal/ext/common.go index a871c531d4..d7c1734b12 100644 --- a/internal/ext/common.go +++ b/internal/ext/common.go @@ -25,6 +25,7 @@ type Flag struct { } type Variant struct { + Default bool `yaml:"default,omitempty" json:"default,omitempty"` Key string `yaml:"key,omitempty" json:"key,omitempty"` Name string `yaml:"name,omitempty" json:"name,omitempty"` Description string `yaml:"description,omitempty" json:"description,omitempty"` diff --git a/internal/ext/exporter.go b/internal/ext/exporter.go index d55ec6feba..8ad0020ada 100644 --- a/internal/ext/exporter.go +++ b/internal/ext/exporter.go @@ -11,15 +11,19 @@ import ( "go.flipt.io/flipt/rpc/flipt" ) -const ( - defaultBatchSize = 25 -) +const defaultBatchSize = 25 var ( - latestVersion = semver.Version{Major: 1, Minor: 2} + v1_0 = semver.Version{Major: 1} + v1_1 = semver.Version{Major: 1, Minor: 1} + v1_2 = semver.Version{Major: 1, Minor: 2} + v1_3 = semver.Version{Major: 1, Minor: 3} + latestVersion = v1_3 + supportedVersions = semver.Versions{ - {Major: 1}, - {Major: 1, Minor: 1}, + v1_0, + v1_1, + v1_2, latestVersion, } ) @@ -146,7 +150,13 @@ func (e *Exporter) Export(ctx context.Context, encoding Encoding, w io.Writer) e } } + defaultVariant := false + if f.DefaultVariant != nil { + defaultVariant = f.DefaultVariant.Id == v.Id + } + flag.Variants = append(flag.Variants, &Variant{ + Default: defaultVariant, Key: v.Key, Name: v.Name, Description: v.Description, diff --git a/internal/ext/exporter_test.go b/internal/ext/exporter_test.go index d01582549d..450858f047 100644 --- a/internal/ext/exporter_test.go +++ b/internal/ext/exporter_test.go @@ -88,6 +88,10 @@ func TestExport(t *testing.T) { Type: flipt.FlagType_VARIANT_FLAG_TYPE, Description: "description", Enabled: true, + DefaultVariant: &flipt.Variant{ + Id: "2", + Key: "foo", + }, Variants: []*flipt.Variant{ { Id: "1", @@ -771,7 +775,7 @@ func TestExport(t *testing.T) { found = ext.NewDecoder(b) ) - // handle newline delimeted JSON + // handle newline delimited JSON for { var exp, fnd any eerr := expected.Decode(&exp) diff --git a/internal/ext/importer.go b/internal/ext/importer.go index afde0ccece..442db941fe 100644 --- a/internal/ext/importer.go +++ b/internal/ext/importer.go @@ -18,6 +18,7 @@ type Creator interface { GetNamespace(context.Context, *flipt.GetNamespaceRequest) (*flipt.Namespace, error) CreateNamespace(context.Context, *flipt.CreateNamespaceRequest) (*flipt.Namespace, error) CreateFlag(context.Context, *flipt.CreateFlagRequest) (*flipt.Flag, error) + UpdateFlag(context.Context, *flipt.UpdateFlagRequest) (*flipt.Flag, error) CreateVariant(context.Context, *flipt.CreateVariantRequest) (*flipt.Variant, error) CreateSegment(context.Context, *flipt.CreateSegmentRequest) (*flipt.Segment, error) CreateConstraint(context.Context, *flipt.CreateConstraintRequest) (*flipt.Constraint, error) @@ -130,10 +131,7 @@ func (i *Importer) Import(ctx context.Context, enc Encoding, r io.Reader) (err e // support explicitly setting flag type from 1.1 if f.Type != "" { - if err := ensureFieldSupported("flag.type", semver.Version{ - Major: 1, - Minor: 1, - }, version); err != nil { + if err := ensureFieldSupported("flag.type", v1_1, version); err != nil { return err } @@ -145,6 +143,8 @@ func (i *Importer) Import(ctx context.Context, enc Encoding, r io.Reader) (err e return fmt.Errorf("creating flag: %w", err) } + var defaultVariantId string + for _, v := range f.Variants { if v == nil { continue @@ -160,6 +160,15 @@ func (i *Importer) Import(ctx context.Context, enc Encoding, r io.Reader) (err e } } + // last variant with default=true will be the default variant when importing + if v.Default { + // support explicitly setting default variant from 1.3 + if err := ensureFieldSupported("variant.default", v1_3, version); err != nil { + return err + } + defaultVariantId = v.Key + } + variant, err := i.creator.CreateVariant(ctx, &flipt.CreateVariantRequest{ FlagKey: f.Key, Key: v.Key, @@ -176,6 +185,21 @@ func (i *Importer) Import(ctx context.Context, enc Encoding, r io.Reader) (err e createdVariants[fmt.Sprintf("%s:%s", flag.Key, variant.Key)] = variant } + if defaultVariantId != "" { + _, err := i.creator.UpdateFlag(ctx, &flipt.UpdateFlagRequest{ + Key: flag.Key, + Name: flag.Name, + Description: flag.Description, + Enabled: flag.Enabled, + NamespaceKey: namespace, + DefaultVariantId: defaultVariantId, + }) + + if err != nil { + return fmt.Errorf("updating flag: %w", err) + } + } + createdFlags[flag.Key] = flag } @@ -233,7 +257,7 @@ func (i *Importer) Import(ctx context.Context, enc Encoding, r io.Reader) (err e // support implicit rank from version >=1.1 rank := int32(r.Rank) - if rank == 0 && version.GE(semver.Version{Major: 1, Minor: 1}) { + if rank == 0 && version.GE(v1_1) { rank = int32(idx) + 1 } @@ -283,10 +307,7 @@ func (i *Importer) Import(ctx context.Context, enc Encoding, r io.Reader) (err e // support explicitly setting flag type from 1.1 if len(f.Rollouts) > 0 { - if err := ensureFieldSupported("flag.rollouts", semver.Version{ - Major: 1, - Minor: 1, - }, version); err != nil { + if err := ensureFieldSupported("flag.rollouts", v1_1, version); err != nil { return err } @@ -322,10 +343,7 @@ func (i *Importer) Import(ctx context.Context, enc Encoding, r io.Reader) (err e // support explicitly setting only "keys" on rules from 1.2 if len(r.Segment.Keys) > 0 { - if err := ensureFieldSupported("flag.rollouts[*].segment.keys", semver.Version{ - Major: 1, - Minor: 2, - }, version); err != nil { + if err := ensureFieldSupported("flag.rollouts[*].segment.keys", v1_2, version); err != nil { return err } diff --git a/internal/ext/importer_test.go b/internal/ext/importer_test.go index 7d2ab6eb2e..2712276565 100644 --- a/internal/ext/importer_test.go +++ b/internal/ext/importer_test.go @@ -22,8 +22,11 @@ type mockCreator struct { createNSReqs []*flipt.CreateNamespaceRequest createNSErr error - flagReqs []*flipt.CreateFlagRequest - flagErr error + createflagReqs []*flipt.CreateFlagRequest + createflagErr error + + updateFlagReqs []*flipt.UpdateFlagRequest + updateFlagErr error variantReqs []*flipt.CreateVariantRequest variantErr error @@ -55,16 +58,34 @@ func (m *mockCreator) CreateNamespace(ctx context.Context, r *flipt.CreateNamesp } func (m *mockCreator) CreateFlag(ctx context.Context, r *flipt.CreateFlagRequest) (*flipt.Flag, error) { - m.flagReqs = append(m.flagReqs, r) - if m.flagErr != nil { - return nil, m.flagErr + m.createflagReqs = append(m.createflagReqs, r) + if m.createflagErr != nil { + return nil, m.createflagErr } return &flipt.Flag{ - Key: r.Key, - Name: r.Name, - Description: r.Description, - Type: r.Type, - Enabled: r.Enabled, + NamespaceKey: r.NamespaceKey, + Key: r.Key, + Name: r.Name, + Description: r.Description, + Type: r.Type, + Enabled: r.Enabled, + }, nil +} + +func (m *mockCreator) UpdateFlag(ctx context.Context, r *flipt.UpdateFlagRequest) (*flipt.Flag, error) { + m.updateFlagReqs = append(m.updateFlagReqs, r) + if m.updateFlagErr != nil { + return nil, m.updateFlagErr + } + return &flipt.Flag{ + NamespaceKey: r.NamespaceKey, + Key: r.Key, + Name: r.Name, + Description: r.Description, + DefaultVariant: &flipt.Variant{ + Id: r.DefaultVariantId, + }, + Enabled: r.Enabled, }, nil } @@ -189,10 +210,106 @@ func TestImport(t *testing.T) { expected *mockCreator }{ { - name: "import with attachment", + name: "import with attachment and default variant", path: "testdata/import", expected: &mockCreator{ - flagReqs: []*flipt.CreateFlagRequest{ + createflagReqs: []*flipt.CreateFlagRequest{ + { + Key: "flag1", + Name: "flag1", + Description: "description", + Type: flipt.FlagType_VARIANT_FLAG_TYPE, + Enabled: true, + }, + { + Key: "flag2", + Name: "flag2", + Description: "a boolean flag", + Type: flipt.FlagType_BOOLEAN_FLAG_TYPE, + Enabled: false, + }, + }, + variantReqs: []*flipt.CreateVariantRequest{ + { + FlagKey: "flag1", + Key: "variant1", + Name: "variant1", + Description: "variant description", + Attachment: compact(t, variantAttachment), + }, + }, + updateFlagReqs: []*flipt.UpdateFlagRequest{ + { + Key: "flag1", + Name: "flag1", + Description: "description", + Enabled: true, + DefaultVariantId: "variant1", + }, + }, + segmentReqs: []*flipt.CreateSegmentRequest{ + { + Key: "segment1", + Name: "segment1", + Description: "description", + MatchType: flipt.MatchType_ANY_MATCH_TYPE, + }, + }, + constraintReqs: []*flipt.CreateConstraintRequest{ + { + SegmentKey: "segment1", + Type: flipt.ComparisonType_STRING_COMPARISON_TYPE, + Property: "fizz", + Operator: "neq", + Value: "buzz", + }, + }, + ruleReqs: []*flipt.CreateRuleRequest{ + { + FlagKey: "flag1", + SegmentKey: "segment1", + Rank: 1, + }, + }, + distributionReqs: []*flipt.CreateDistributionRequest{ + { + RuleId: "static_rule_id", + VariantId: "static_variant_id", + FlagKey: "flag1", + Rollout: 100, + }, + }, + rolloutReqs: []*flipt.CreateRolloutRequest{ + { + FlagKey: "flag2", + Description: "enabled for internal users", + Rank: 1, + Rule: &flipt.CreateRolloutRequest_Segment{ + Segment: &flipt.RolloutSegment{ + SegmentKey: "internal_users", + Value: true, + }, + }, + }, + { + FlagKey: "flag2", + Description: "enabled for 50%", + Rank: 2, + Rule: &flipt.CreateRolloutRequest_Threshold{ + Threshold: &flipt.RolloutThreshold{ + Percentage: 50.0, + Value: true, + }, + }, + }, + }, + }, + }, + { + name: "import with attachment", + path: "testdata/import_with_attachment", + expected: &mockCreator{ + createflagReqs: []*flipt.CreateFlagRequest{ { Key: "flag1", Name: "flag1", @@ -279,7 +396,7 @@ func TestImport(t *testing.T) { name: "import without attachment", path: "testdata/import_no_attachment", expected: &mockCreator{ - flagReqs: []*flipt.CreateFlagRequest{ + createflagReqs: []*flipt.CreateFlagRequest{ { Key: "flag1", Name: "flag1", @@ -365,7 +482,7 @@ func TestImport(t *testing.T) { name: "import with implicit rule ranks", path: "testdata/import_implicit_rule_rank", expected: &mockCreator{ - flagReqs: []*flipt.CreateFlagRequest{ + createflagReqs: []*flipt.CreateFlagRequest{ { Key: "flag1", Name: "flag1", @@ -452,7 +569,7 @@ func TestImport(t *testing.T) { name: "import with multiple segments", path: "testdata/import_rule_multiple_segments", expected: &mockCreator{ - flagReqs: []*flipt.CreateFlagRequest{ + createflagReqs: []*flipt.CreateFlagRequest{ { Key: "flag1", Name: "flag1", @@ -539,7 +656,7 @@ func TestImport(t *testing.T) { name: "import v1", path: "testdata/import_v1", expected: &mockCreator{ - flagReqs: []*flipt.CreateFlagRequest{ + createflagReqs: []*flipt.CreateFlagRequest{ { Key: "flag1", Name: "flag1", @@ -595,7 +712,7 @@ func TestImport(t *testing.T) { name: "import v1.1", path: "testdata/import_v1_1", expected: &mockCreator{ - flagReqs: []*flipt.CreateFlagRequest{ + createflagReqs: []*flipt.CreateFlagRequest{ { Key: "flag1", Name: "flag1", @@ -714,7 +831,7 @@ func TestImport_Export(t *testing.T) { err = importer.Import(context.Background(), EncodingYML, in) require.NoError(t, err) - assert.Equal(t, "default", creator.flagReqs[0].NamespaceKey) + assert.Equal(t, "default", creator.createflagReqs[0].NamespaceKey) } func TestImport_InvalidVersion(t *testing.T) { @@ -827,7 +944,7 @@ func TestImport_Namespaces_Mix_And_Match(t *testing.T) { assert.NoError(t, err) assert.Len(t, creator.getNSReqs, tc.expectedGetNSReqs) - assert.Len(t, creator.flagReqs, tc.expectedCreateFlagReqs) + assert.Len(t, creator.createflagReqs, tc.expectedCreateFlagReqs) assert.Len(t, creator.segmentReqs, tc.expectedCreateSegmentReqs) }) } diff --git a/internal/ext/testdata/export.json b/internal/ext/testdata/export.json index e5101f9055..c8d8629147 100644 --- a/internal/ext/testdata/export.json +++ b/internal/ext/testdata/export.json @@ -1 +1,91 @@ -{"version":"1.2","namespace":"default","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","attachment":{"pi":3.141,"happy":true,"name":"Niels","nothing":null,"answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}},{"key":"foo"}],"rules":[{"segment":"segment1","distributions":[{"variant":"variant1","rollout":100}]},{"segment":{"keys":["segment1","segment2"],"operator":"AND_SEGMENT_OPERATOR"}}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"foo","operator":"eq","value":"baz","description":"desc"},{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz","description":"desc"}]},{"key":"segment2","name":"segment2","match_type":"ANY_MATCH_TYPE","description":"description"}]} +{ + "version": "1.3", + "namespace": "default", + "flags": [ + { + "key": "flag1", + "name": "flag1", + "type": "VARIANT_FLAG_TYPE", + "description": "description", + "enabled": true, + "variants": [ + { + "key": "variant1", + "name": "variant1", + "attachment": { + "pi": 3.141, + "happy": true, + "name": "Niels", + "nothing": null, + "answer": { "everything": 42 }, + "list": [1, 0, 2], + "object": { "currency": "USD", "value": 42.99 } + } + }, + { + "key": "foo", + "default": true + } + ], + "rules": [ + { + "segment": "segment1", + "distributions": [{ "variant": "variant1", "rollout": 100 }] + }, + { + "segment": { + "keys": ["segment1", "segment2"], + "operator": "AND_SEGMENT_OPERATOR" + } + } + ] + }, + { + "key": "flag2", + "name": "flag2", + "type": "BOOLEAN_FLAG_TYPE", + "description": "a boolean flag", + "enabled": false, + "rollouts": [ + { + "description": "enabled for internal users", + "segment": { "key": "internal_users", "value": true } + }, + { + "description": "enabled for 50%", + "threshold": { "percentage": 50, "value": true } + } + ] + } + ], + "segments": [ + { + "key": "segment1", + "name": "segment1", + "match_type": "ANY_MATCH_TYPE", + "description": "description", + "constraints": [ + { + "type": "STRING_COMPARISON_TYPE", + "property": "foo", + "operator": "eq", + "value": "baz", + "description": "desc" + }, + { + "type": "STRING_COMPARISON_TYPE", + "property": "fizz", + "operator": "neq", + "value": "buzz", + "description": "desc" + } + ] + }, + { + "key": "segment2", + "name": "segment2", + "match_type": "ANY_MATCH_TYPE", + "description": "description" + } + ] +} diff --git a/internal/ext/testdata/export.yml b/internal/ext/testdata/export.yml index c82cd0820a..986b3cb88c 100644 --- a/internal/ext/testdata/export.yml +++ b/internal/ext/testdata/export.yml @@ -1,4 +1,4 @@ -version: "1.2" +version: "1.3" namespace: default flags: - key: flag1 @@ -24,6 +24,7 @@ flags: currency: USD value: 42.99 - key: foo + default: true rules: - segment: segment1 distributions: @@ -31,8 +32,8 @@ flags: rollout: 100 - segment: keys: - - segment1 - - segment2 + - segment1 + - segment2 operator: AND_SEGMENT_OPERATOR - key: flag2 name: flag2 diff --git a/internal/ext/testdata/export_all_namespaces.json b/internal/ext/testdata/export_all_namespaces.json index 40dbd9667b..3611adc380 100644 --- a/internal/ext/testdata/export_all_namespaces.json +++ b/internal/ext/testdata/export_all_namespaces.json @@ -1,3 +1,3 @@ -{"version":"1.2","namespace":"default"} +{"version":"1.3","namespace":"default"} {"namespace":"foo","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","attachment":{"pi":3.141,"happy":true,"name":"Niels","nothing":null,"answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}},{"key":"foo"}],"rules":[{"segment":"segment1","distributions":[{"variant":"variant1","rollout":100}]},{"segment":{"keys":["segment1","segment2"],"operator":"AND_SEGMENT_OPERATOR"}}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"foo","operator":"eq","value":"baz","description":"desc"},{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz","description":"desc"}]},{"key":"segment2","name":"segment2","match_type":"ANY_MATCH_TYPE","description":"description"}]} {"namespace":"bar","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","attachment":{"pi":3.141,"happy":true,"name":"Niels","nothing":null,"answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}},{"key":"foo"}],"rules":[{"segment":"segment1","distributions":[{"variant":"variant1","rollout":100}]},{"segment":{"keys":["segment1","segment2"],"operator":"AND_SEGMENT_OPERATOR"}}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"foo","operator":"eq","value":"baz","description":"desc"},{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz","description":"desc"}]},{"key":"segment2","name":"segment2","match_type":"ANY_MATCH_TYPE","description":"description"}]} diff --git a/internal/ext/testdata/export_all_namespaces.yml b/internal/ext/testdata/export_all_namespaces.yml index 635c07be56..6ee1608dda 100644 --- a/internal/ext/testdata/export_all_namespaces.yml +++ b/internal/ext/testdata/export_all_namespaces.yml @@ -1,4 +1,4 @@ -version: "1.2" +version: "1.3" namespace: default --- namespace: foo @@ -33,8 +33,8 @@ flags: rollout: 100 - segment: keys: - - segment1 - - segment2 + - segment1 + - segment2 operator: AND_SEGMENT_OPERATOR - key: flag2 name: flag2 @@ -103,8 +103,8 @@ flags: rollout: 100 - segment: keys: - - segment1 - - segment2 + - segment1 + - segment2 operator: AND_SEGMENT_OPERATOR - key: flag2 name: flag2 diff --git a/internal/ext/testdata/export_default_and_foo.json b/internal/ext/testdata/export_default_and_foo.json index 3963ba84c1..117a87d5de 100644 --- a/internal/ext/testdata/export_default_and_foo.json +++ b/internal/ext/testdata/export_default_and_foo.json @@ -1,2 +1,2 @@ -{"version":"1.2","namespace":"default","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","attachment":{"pi":3.141,"happy":true,"name":"Niels","nothing":null,"answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}},{"key":"foo"}],"rules":[{"segment":"segment1","distributions":[{"variant":"variant1","rollout":100}]},{"segment":{"keys":["segment1","segment2"],"operator":"AND_SEGMENT_OPERATOR"}}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"foo","operator":"eq","value":"baz","description":"desc"},{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz","description":"desc"}]},{"key":"segment2","name":"segment2","match_type":"ANY_MATCH_TYPE","description":"description"}]} +{"version":"1.3","namespace":"default","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","attachment":{"pi":3.141,"happy":true,"name":"Niels","nothing":null,"answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}},{"key":"foo"}],"rules":[{"segment":"segment1","distributions":[{"variant":"variant1","rollout":100}]},{"segment":{"keys":["segment1","segment2"],"operator":"AND_SEGMENT_OPERATOR"}}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"foo","operator":"eq","value":"baz","description":"desc"},{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz","description":"desc"}]},{"key":"segment2","name":"segment2","match_type":"ANY_MATCH_TYPE","description":"description"}]} {"namespace":"foo","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","attachment":{"pi":3.141,"happy":true,"name":"Niels","nothing":null,"answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}},{"key":"foo"}],"rules":[{"segment":"segment1","distributions":[{"variant":"variant1","rollout":100}]},{"segment":{"keys":["segment1","segment2"],"operator":"AND_SEGMENT_OPERATOR"}}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"foo","operator":"eq","value":"baz","description":"desc"},{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz","description":"desc"}]},{"key":"segment2","name":"segment2","match_type":"ANY_MATCH_TYPE","description":"description"}]} diff --git a/internal/ext/testdata/export_default_and_foo.yml b/internal/ext/testdata/export_default_and_foo.yml index abe67ae136..a097bbaabc 100644 --- a/internal/ext/testdata/export_default_and_foo.yml +++ b/internal/ext/testdata/export_default_and_foo.yml @@ -1,4 +1,4 @@ -version: "1.2" +version: "1.3" namespace: default flags: - key: flag1 @@ -31,8 +31,8 @@ flags: rollout: 100 - segment: keys: - - segment1 - - segment2 + - segment1 + - segment2 operator: AND_SEGMENT_OPERATOR - key: flag2 name: flag2 @@ -101,8 +101,8 @@ flags: rollout: 100 - segment: keys: - - segment1 - - segment2 + - segment1 + - segment2 operator: AND_SEGMENT_OPERATOR - key: flag2 name: flag2 diff --git a/internal/ext/testdata/import.json b/internal/ext/testdata/import.json index 8f71dd37b4..4b898ad0d2 100644 --- a/internal/ext/testdata/import.json +++ b/internal/ext/testdata/import.json @@ -1 +1,67 @@ -{"flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","description":"variant description","attachment":{"pi":3.141,"happy":true,"name":"Niels","answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}}],"rules":[{"segment":"segment1","rank":1,"distributions":[{"variant":"variant1","rollout":100}]}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz"}]}]} +{ + "flags": [ + { + "key": "flag1", + "name": "flag1", + "type": "VARIANT_FLAG_TYPE", + "description": "description", + "enabled": true, + "variants": [ + { + "key": "variant1", + "name": "variant1", + "description": "variant description", + "default": true, + "attachment": { + "pi": 3.141, + "happy": true, + "name": "Niels", + "answer": { "everything": 42 }, + "list": [1, 0, 2], + "object": { "currency": "USD", "value": 42.99 } + } + } + ], + "rules": [ + { + "segment": "segment1", + "rank": 1, + "distributions": [{ "variant": "variant1", "rollout": 100 }] + } + ] + }, + { + "key": "flag2", + "name": "flag2", + "type": "BOOLEAN_FLAG_TYPE", + "description": "a boolean flag", + "enabled": false, + "rollouts": [ + { + "description": "enabled for internal users", + "segment": { "key": "internal_users", "value": true } + }, + { + "description": "enabled for 50%", + "threshold": { "percentage": 50, "value": true } + } + ] + } + ], + "segments": [ + { + "key": "segment1", + "name": "segment1", + "match_type": "ANY_MATCH_TYPE", + "description": "description", + "constraints": [ + { + "type": "STRING_COMPARISON_TYPE", + "property": "fizz", + "operator": "neq", + "value": "buzz" + } + ] + } + ] +} diff --git a/internal/ext/testdata/import.yml b/internal/ext/testdata/import.yml index 775447c336..75e08bbdf8 100644 --- a/internal/ext/testdata/import.yml +++ b/internal/ext/testdata/import.yml @@ -8,6 +8,7 @@ flags: - key: variant1 name: variant1 description: variant description + default: true attachment: pi: 3.141 happy: true diff --git a/internal/ext/testdata/import_rule_multiple_segments.json b/internal/ext/testdata/import_rule_multiple_segments.json index 93ae2e1db7..0b36729996 100644 --- a/internal/ext/testdata/import_rule_multiple_segments.json +++ b/internal/ext/testdata/import_rule_multiple_segments.json @@ -1 +1,68 @@ -{"flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","description":"variant description","attachment":{"pi":3.141,"happy":true,"name":"Niels","answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}}],"rules":[{"segment":{"keys":["segment1"],"operator":"OR_SEGMENT_OPERATOR"},"distributions":[{"variant":"variant1","rollout":100}]}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz"}]}]} +{ + "flags": [ + { + "key": "flag1", + "name": "flag1", + "type": "VARIANT_FLAG_TYPE", + "description": "description", + "enabled": true, + "variants": [ + { + "key": "variant1", + "name": "variant1", + "description": "variant description", + "attachment": { + "pi": 3.141, + "happy": true, + "name": "Niels", + "answer": { "everything": 42 }, + "list": [1, 0, 2], + "object": { "currency": "USD", "value": 42.99 } + } + } + ], + "rules": [ + { + "segment": { + "keys": ["segment1"], + "operator": "OR_SEGMENT_OPERATOR" + }, + "distributions": [{ "variant": "variant1", "rollout": 100 }] + } + ] + }, + { + "key": "flag2", + "name": "flag2", + "type": "BOOLEAN_FLAG_TYPE", + "description": "a boolean flag", + "enabled": false, + "rollouts": [ + { + "description": "enabled for internal users", + "segment": { "key": "internal_users", "value": true } + }, + { + "description": "enabled for 50%", + "threshold": { "percentage": 50, "value": true } + } + ] + } + ], + "segments": [ + { + "key": "segment1", + "name": "segment1", + "match_type": "ANY_MATCH_TYPE", + "description": "description", + "constraints": [ + { + "type": "STRING_COMPARISON_TYPE", + "property": "fizz", + "operator": "neq", + "value": "buzz" + } + ] + } + ] +} diff --git a/internal/ext/testdata/import_single_namespace_foo.json b/internal/ext/testdata/import_single_namespace_foo.json index 3daedb0a99..ca30228827 100644 --- a/internal/ext/testdata/import_single_namespace_foo.json +++ b/internal/ext/testdata/import_single_namespace_foo.json @@ -1 +1,67 @@ -{"namespace":"foo","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","description":"variant description","attachment":{"pi":3.141,"happy":true,"name":"Niels","answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}}],"rules":[{"segment":"segment1","rank":1,"distributions":[{"variant":"variant1","rollout":100}]}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz"}]}]} +{ + "namespace": "foo", + "flags": [ + { + "key": "flag1", + "name": "flag1", + "type": "VARIANT_FLAG_TYPE", + "description": "description", + "enabled": true, + "variants": [ + { + "key": "variant1", + "name": "variant1", + "description": "variant description", + "attachment": { + "pi": 3.141, + "happy": true, + "name": "Niels", + "answer": { "everything": 42 }, + "list": [1, 0, 2], + "object": { "currency": "USD", "value": 42.99 } + } + } + ], + "rules": [ + { + "segment": "segment1", + "rank": 1, + "distributions": [{ "variant": "variant1", "rollout": 100 }] + } + ] + }, + { + "key": "flag2", + "name": "flag2", + "type": "BOOLEAN_FLAG_TYPE", + "description": "a boolean flag", + "enabled": false, + "rollouts": [ + { + "description": "enabled for internal users", + "segment": { "key": "internal_users", "value": true } + }, + { + "description": "enabled for 50%", + "threshold": { "percentage": 50, "value": true } + } + ] + } + ], + "segments": [ + { + "key": "segment1", + "name": "segment1", + "match_type": "ANY_MATCH_TYPE", + "description": "description", + "constraints": [ + { + "type": "STRING_COMPARISON_TYPE", + "property": "fizz", + "operator": "neq", + "value": "buzz" + } + ] + } + ] +} diff --git a/internal/ext/testdata/import_v1.json b/internal/ext/testdata/import_v1.json index bad0a84dcb..f03a5c131a 100644 --- a/internal/ext/testdata/import_v1.json +++ b/internal/ext/testdata/import_v1.json @@ -1 +1,49 @@ -{"version":"1.0","flags":[{"key":"flag1","name":"flag1","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","description":"variant description","attachment":{"pi":3.141,"happy":true,"name":"Niels","answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}}],"rules":[{"segment":"segment1","rank":1,"distributions":[{"variant":"variant1","rollout":100}]}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz"}]}]} +{ + "version": "1.0", + "flags": [ + { + "key": "flag1", + "name": "flag1", + "description": "description", + "enabled": true, + "variants": [ + { + "key": "variant1", + "name": "variant1", + "description": "variant description", + "attachment": { + "pi": 3.141, + "happy": true, + "name": "Niels", + "answer": { "everything": 42 }, + "list": [1, 0, 2], + "object": { "currency": "USD", "value": 42.99 } + } + } + ], + "rules": [ + { + "segment": "segment1", + "rank": 1, + "distributions": [{ "variant": "variant1", "rollout": 100 }] + } + ] + } + ], + "segments": [ + { + "key": "segment1", + "name": "segment1", + "match_type": "ANY_MATCH_TYPE", + "description": "description", + "constraints": [ + { + "type": "STRING_COMPARISON_TYPE", + "property": "fizz", + "operator": "neq", + "value": "buzz" + } + ] + } + ] +} diff --git a/internal/ext/testdata/import_v1_1.json b/internal/ext/testdata/import_v1_1.json index 48382a0974..1258363b4c 100644 --- a/internal/ext/testdata/import_v1_1.json +++ b/internal/ext/testdata/import_v1_1.json @@ -1 +1,67 @@ -{"version":"1.1","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true,"variants":[{"key":"variant1","name":"variant1","description":"variant description","attachment":{"pi":3.141,"happy":true,"name":"Niels","answer":{"everything":42},"list":[1,0,2],"object":{"currency":"USD","value":42.99}}}],"rules":[{"segment":"segment1","rank":1,"distributions":[{"variant":"variant1","rollout":100}]}]},{"key":"flag2","name":"flag2","type":"BOOLEAN_FLAG_TYPE","description":"a boolean flag","enabled":false,"rollouts":[{"description":"enabled for internal users","segment":{"key":"internal_users","value":true}},{"description":"enabled for 50%","threshold":{"percentage":50,"value":true}}]}],"segments":[{"key":"segment1","name":"segment1","match_type":"ANY_MATCH_TYPE","description":"description","constraints":[{"type":"STRING_COMPARISON_TYPE","property":"fizz","operator":"neq","value":"buzz"}]}]} +{ + "version": "1.1", + "flags": [ + { + "key": "flag1", + "name": "flag1", + "type": "VARIANT_FLAG_TYPE", + "description": "description", + "enabled": true, + "variants": [ + { + "key": "variant1", + "name": "variant1", + "description": "variant description", + "attachment": { + "pi": 3.141, + "happy": true, + "name": "Niels", + "answer": { "everything": 42 }, + "list": [1, 0, 2], + "object": { "currency": "USD", "value": 42.99 } + } + } + ], + "rules": [ + { + "segment": "segment1", + "rank": 1, + "distributions": [{ "variant": "variant1", "rollout": 100 }] + } + ] + }, + { + "key": "flag2", + "name": "flag2", + "type": "BOOLEAN_FLAG_TYPE", + "description": "a boolean flag", + "enabled": false, + "rollouts": [ + { + "description": "enabled for internal users", + "segment": { "key": "internal_users", "value": true } + }, + { + "description": "enabled for 50%", + "threshold": { "percentage": 50, "value": true } + } + ] + } + ], + "segments": [ + { + "key": "segment1", + "name": "segment1", + "match_type": "ANY_MATCH_TYPE", + "description": "description", + "constraints": [ + { + "type": "STRING_COMPARISON_TYPE", + "property": "fizz", + "operator": "neq", + "value": "buzz" + } + ] + } + ] +} diff --git a/internal/ext/testdata/import_v1_flag_type_not_supported.json b/internal/ext/testdata/import_v1_flag_type_not_supported.json index 07734fb73b..27d7776272 100644 --- a/internal/ext/testdata/import_v1_flag_type_not_supported.json +++ b/internal/ext/testdata/import_v1_flag_type_not_supported.json @@ -1 +1,12 @@ -{"version":"1.0","flags":[{"key":"flag1","name":"flag1","type":"VARIANT_FLAG_TYPE","description":"description","enabled":true}]} +{ + "version": "1.0", + "flags": [ + { + "key": "flag1", + "name": "flag1", + "type": "VARIANT_FLAG_TYPE", + "description": "description", + "enabled": true + } + ] +} diff --git a/internal/ext/testdata/import_v1_rollouts_not_supported.json b/internal/ext/testdata/import_v1_rollouts_not_supported.json index e766b87823..3a5f96292b 100644 --- a/internal/ext/testdata/import_v1_rollouts_not_supported.json +++ b/internal/ext/testdata/import_v1_rollouts_not_supported.json @@ -1 +1,17 @@ -{"version":"1.0","flags":[{"key":"flag1","name":"flag1","description":"description","enabled":false,"rollouts":[{"description":"some rollout","threshold":{"percentage":50,"value":true}}]}]} +{ + "version": "1.0", + "flags": [ + { + "key": "flag1", + "name": "flag1", + "description": "description", + "enabled": false, + "rollouts": [ + { + "description": "some rollout", + "threshold": { "percentage": 50, "value": true } + } + ] + } + ] +} diff --git a/internal/ext/testdata/import_with_attachment.json b/internal/ext/testdata/import_with_attachment.json new file mode 100644 index 0000000000..e6b53164a8 --- /dev/null +++ b/internal/ext/testdata/import_with_attachment.json @@ -0,0 +1,66 @@ +{ + "flags": [ + { + "key": "flag1", + "name": "flag1", + "type": "VARIANT_FLAG_TYPE", + "description": "description", + "enabled": true, + "variants": [ + { + "key": "variant1", + "name": "variant1", + "description": "variant description", + "attachment": { + "pi": 3.141, + "happy": true, + "name": "Niels", + "answer": { "everything": 42 }, + "list": [1, 0, 2], + "object": { "currency": "USD", "value": 42.99 } + } + } + ], + "rules": [ + { + "segment": "segment1", + "rank": 1, + "distributions": [{ "variant": "variant1", "rollout": 100 }] + } + ] + }, + { + "key": "flag2", + "name": "flag2", + "type": "BOOLEAN_FLAG_TYPE", + "description": "a boolean flag", + "enabled": false, + "rollouts": [ + { + "description": "enabled for internal users", + "segment": { "key": "internal_users", "value": true } + }, + { + "description": "enabled for 50%", + "threshold": { "percentage": 50, "value": true } + } + ] + } + ], + "segments": [ + { + "key": "segment1", + "name": "segment1", + "match_type": "ANY_MATCH_TYPE", + "description": "description", + "constraints": [ + { + "type": "STRING_COMPARISON_TYPE", + "property": "fizz", + "operator": "neq", + "value": "buzz" + } + ] + } + ] +} diff --git a/internal/ext/testdata/import_with_attachment.yml b/internal/ext/testdata/import_with_attachment.yml new file mode 100644 index 0000000000..775447c336 --- /dev/null +++ b/internal/ext/testdata/import_with_attachment.yml @@ -0,0 +1,53 @@ +flags: + - key: flag1 + name: flag1 + type: "VARIANT_FLAG_TYPE" + description: description + enabled: true + variants: + - key: variant1 + name: variant1 + description: variant description + attachment: + pi: 3.141 + happy: true + name: Niels + answer: + everything: 42 + list: + - 1 + - 0 + - 2 + object: + currency: USD + value: 42.99 + rules: + - segment: segment1 + rank: 1 + distributions: + - variant: variant1 + rollout: 100 + - key: flag2 + name: flag2 + type: "BOOLEAN_FLAG_TYPE" + description: a boolean flag + enabled: false + rollouts: + - description: enabled for internal users + segment: + key: internal_users + value: true + - description: enabled for 50% + threshold: + percentage: 50 + value: true +segments: + - key: segment1 + name: segment1 + match_type: "ANY_MATCH_TYPE" + description: description + constraints: + - type: STRING_COMPARISON_TYPE + property: fizz + operator: neq + value: buzz diff --git a/internal/server/evaluation/data/server.go b/internal/server/evaluation/data/server.go index cfdbc721c8..481bc7cc6d 100644 --- a/internal/server/evaluation/data/server.go +++ b/internal/server/evaluation/data/server.go @@ -97,7 +97,26 @@ func toEvaluationRolloutType(r flipt.RolloutType) evaluation.EvaluationRolloutTy return evaluation.EvaluationRolloutType_UNKNOWN_ROLLOUT_TYPE } -var supportsEntityIdConstraintMinVersion = semver.MustParse("1.38.0") +type minVersion struct { + semver.Version + msg string +} + +func (m minVersion) String() string { + return m.msg +} + +var ( + supportsEntityIdConstraintMinVersion = minVersion{ + Version: semver.MustParse("1.38.0"), + msg: "skipping `entity_id` constraint type to support older client; upgrade client to allow `entity_id` constraint type", + } + + supportsDefaultVariantMinVersion = minVersion{ + Version: semver.MustParse("1.47.0"), + msg: "skipping `default_variant` to support older client; upgrade client to allow `default_variant`", + } +) func (srv *Server) EvaluationSnapshotNamespace(ctx context.Context, r *evaluation.EvaluationNamespaceSnapshotRequest) (*evaluation.EvaluationNamespaceSnapshot, error) { @@ -180,7 +199,21 @@ func (srv *Server) EvaluationSnapshotNamespace(ctx context.Context, r *evaluatio } flagKey := storage.NewResource(namespaceKey, f.Key, storage.WithReference(reference)) - if f.Type == flipt.FlagType_VARIANT_FLAG_TYPE { + switch f.Type { + // variant flag + case flipt.FlagType_VARIANT_FLAG_TYPE: + if f.DefaultVariant != nil { + if supportedServerVersion.LT(supportsDefaultVariantMinVersion.Version) { + srv.logger.Warn(supportsDefaultVariantMinVersion.String(), zap.String("namespace", f.NamespaceKey), zap.String("flag", f.Key)) + } else { + flag.DefaultVariant = &evaluation.EvaluationVariant{ + Id: f.DefaultVariant.Id, + Key: f.DefaultVariant.Key, + Attachment: f.DefaultVariant.Attachment, + } + } + } + rules, err := srv.store.GetEvaluationRules(ctx, flagKey) if err != nil { return nil, fmt.Errorf("getting rules for flag %q: %w", f.Key, err) @@ -208,8 +241,8 @@ func (srv *Server) EvaluationSnapshotNamespace(ctx context.Context, r *evaluatio typ := toEvaluationConstraintComparisonType(c.Type) // see: https://github.com/flipt-io/flipt/pull/2791 if typ == evaluation.EvaluationConstraintComparisonType_ENTITY_ID_CONSTRAINT_COMPARISON_TYPE { - if supportedServerVersion.LT(supportsEntityIdConstraintMinVersion) { - srv.logger.Warn("skipping `entity_id` constraint type to support older client; upgrade client to allow `entity_id` constraint type", zap.String("namespace", f.NamespaceKey), zap.String("flag", f.Key)) + if supportedServerVersion.LT(supportsEntityIdConstraintMinVersion.Version) { + srv.logger.Warn(supportsEntityIdConstraintMinVersion.String(), zap.String("namespace", f.NamespaceKey), zap.String("flag", f.Key)) typ = evaluation.EvaluationConstraintComparisonType_UNKNOWN_CONSTRAINT_COMPARISON_TYPE } } @@ -247,9 +280,9 @@ func (srv *Server) EvaluationSnapshotNamespace(ctx context.Context, r *evaluatio } } - } - if f.Type == flipt.FlagType_BOOLEAN_FLAG_TYPE { + // boolean flag + case flipt.FlagType_BOOLEAN_FLAG_TYPE: rollouts, err := srv.store.GetEvaluationRollouts(ctx, flagKey) if err != nil { return nil, fmt.Errorf("getting rollout rules for flag %q: %w", f.Key, err) @@ -293,8 +326,8 @@ func (srv *Server) EvaluationSnapshotNamespace(ctx context.Context, r *evaluatio typ := toEvaluationConstraintComparisonType(c.Type) // see: https://github.com/flipt-io/flipt/pull/2791 if typ == evaluation.EvaluationConstraintComparisonType_ENTITY_ID_CONSTRAINT_COMPARISON_TYPE { - if supportedServerVersion.LT(supportsEntityIdConstraintMinVersion) { - srv.logger.Warn("skipping `entity_id` constraint type to support older client; upgrade client to allow `entity_id` constraint type", zap.String("namespace", f.NamespaceKey), zap.String("flag", f.Key)) + if supportedServerVersion.LT(supportsEntityIdConstraintMinVersion.Version) { + srv.logger.Warn(supportsEntityIdConstraintMinVersion.String(), zap.String("namespace", f.NamespaceKey), zap.String("flag", f.Key)) typ = evaluation.EvaluationConstraintComparisonType_UNKNOWN_CONSTRAINT_COMPARISON_TYPE } } diff --git a/internal/server/evaluation/evaluation.go b/internal/server/evaluation/evaluation.go index e997a43e22..7ef34b56e4 100644 --- a/internal/server/evaluation/evaluation.go +++ b/internal/server/evaluation/evaluation.go @@ -70,6 +70,8 @@ func (s *Server) variant(ctx context.Context, flag *flipt.Flag, r *rpcevaluation reason = rpcevaluation.EvaluationReason_MATCH_EVALUATION_REASON case flipt.EvaluationReason_FLAG_DISABLED_EVALUATION_REASON: reason = rpcevaluation.EvaluationReason_FLAG_DISABLED_EVALUATION_REASON + case flipt.EvaluationReason_DEFAULT_EVALUATION_REASON: + reason = rpcevaluation.EvaluationReason_DEFAULT_EVALUATION_REASON default: reason = rpcevaluation.EvaluationReason_UNKNOWN_EVALUATION_REASON } diff --git a/internal/server/evaluation/legacy_evaluator.go b/internal/server/evaluation/legacy_evaluator.go index 6a6e6d7934..c2886900f8 100644 --- a/internal/server/evaluation/legacy_evaluator.go +++ b/internal/server/evaluation/legacy_evaluator.go @@ -94,6 +94,12 @@ func (e *Evaluator) Evaluate(ctx context.Context, flag *flipt.Flag, r *evaluatio if !flag.Enabled { resp.Match = false resp.Reason = flipt.EvaluationReason_FLAG_DISABLED_EVALUATION_REASON + + if flag.DefaultVariant != nil { + resp.Value = flag.DefaultVariant.Key + resp.Attachment = flag.DefaultVariant.Attachment + } + return resp, nil } @@ -105,6 +111,11 @@ func (e *Evaluator) Evaluate(ctx context.Context, flag *flipt.Flag, r *evaluatio if len(rules) == 0 { e.logger.Debug("no rules match") + if flag.DefaultVariant != nil { + resp.Reason = flipt.EvaluationReason_DEFAULT_EVALUATION_REASON + resp.Value = flag.DefaultVariant.Key + resp.Attachment = flag.DefaultVariant.Attachment + } return resp, nil } @@ -185,10 +196,15 @@ func (e *Evaluator) Evaluate(ctx context.Context, flag *flipt.Flag, r *evaluatio } // no distributions for rule + // match is true here because it did match the segment/rule if len(validDistributions) == 0 { e.logger.Info("no distributions for rule") resp.Match = true resp.Reason = flipt.EvaluationReason_MATCH_EVALUATION_REASON + if flag.DefaultVariant != nil { + resp.Value = flag.DefaultVariant.Key + resp.Attachment = flag.DefaultVariant.Attachment + } return resp, nil } @@ -202,8 +218,13 @@ func (e *Evaluator) Evaluate(ctx context.Context, flag *flipt.Flag, r *evaluatio // if index is outside of our existing buckets then it does not match any distribution if index == len(validDistributions) { - resp.Match = false e.logger.Debug("did not match any distributions") + resp.Match = false + if flag.DefaultVariant != nil { + resp.Reason = flipt.EvaluationReason_DEFAULT_EVALUATION_REASON + resp.Value = flag.DefaultVariant.Key + resp.Attachment = flag.DefaultVariant.Attachment + } return resp, nil } diff --git a/internal/server/evaluation/legacy_evaluator_test.go b/internal/server/evaluation/legacy_evaluator_test.go index 56c480c6ff..6b8d23dfbe 100644 --- a/internal/server/evaluation/legacy_evaluator_test.go +++ b/internal/server/evaluation/legacy_evaluator_test.go @@ -861,10 +861,26 @@ var ( Key: "foo", Enabled: true, } + enabledFlagWithDefaultVariant = &flipt.Flag{ + Key: "foo", + Enabled: true, + DefaultVariant: &flipt.Variant{ + Key: "bar", + Attachment: `{ "bar": "baz" }`, + }, + } disabledFlag = &flipt.Flag{ Key: "foo", Enabled: false, } + disabledFlagWithDefaultVariant = &flipt.Flag{ + Key: "foo", + Enabled: false, + DefaultVariant: &flipt.Variant{ + Key: "bar", + Attachment: `{ "bar": "baz" }`, + }, + } ) func TestEvaluator_FlagDisabled(t *testing.T) { @@ -884,6 +900,30 @@ func TestEvaluator_FlagDisabled(t *testing.T) { assert.NoError(t, err) assert.False(t, resp.Match) + assert.Empty(t, resp.Value) + assert.Empty(t, resp.Attachment) + assert.Equal(t, flipt.EvaluationReason_FLAG_DISABLED_EVALUATION_REASON, resp.Reason) +} + +func TestEvaluator_FlagDisabled_DefaultVariant(t *testing.T) { + var ( + store = &evaluationStoreMock{} + logger = zaptest.NewLogger(t) + s = NewEvaluator(logger, store) + ) + + resp, err := s.Evaluate(context.TODO(), disabledFlagWithDefaultVariant, &evaluation.EvaluationRequest{ + EntityId: "1", + FlagKey: "foo", + Context: map[string]string{ + "bar": "boz", + }, + }) + + assert.NoError(t, err) + assert.False(t, resp.Match) + assert.Equal(t, "bar", resp.Value) + assert.Equal(t, `{ "bar": "baz" }`, resp.Attachment) assert.Equal(t, flipt.EvaluationReason_FLAG_DISABLED_EVALUATION_REASON, resp.Reason) } @@ -933,6 +973,30 @@ func TestEvaluator_FlagNoRules(t *testing.T) { assert.Equal(t, flipt.EvaluationReason_UNKNOWN_EVALUATION_REASON, resp.Reason) } +func TestEvaluator_FlagNoRules_DefaultVariant(t *testing.T) { + var ( + store = &evaluationStoreMock{} + logger = zaptest.NewLogger(t) + s = NewEvaluator(logger, store) + ) + + store.On("GetEvaluationRules", mock.Anything, storage.NewResource("", "foo")).Return([]*storage.EvaluationRule{}, nil) + + resp, err := s.Evaluate(context.TODO(), enabledFlagWithDefaultVariant, &evaluation.EvaluationRequest{ + EntityId: "1", + FlagKey: "foo", + Context: map[string]string{ + "bar": "boz", + }, + }) + + assert.NoError(t, err) + assert.False(t, resp.Match) + assert.Equal(t, "bar", resp.Value) + assert.Equal(t, `{ "bar": "baz" }`, resp.Attachment) + assert.Equal(t, flipt.EvaluationReason_DEFAULT_EVALUATION_REASON, resp.Reason) +} + func TestEvaluator_ErrorGettingRules(t *testing.T) { var ( store = &evaluationStoreMock{} @@ -1242,6 +1306,57 @@ func TestEvaluator_MatchAll_NoVariants_NoDistributions(t *testing.T) { } } +func TestEvaluator_MatchAll_NoDistributions_DefaultVariant(t *testing.T) { + var ( + store = &evaluationStoreMock{} + logger = zaptest.NewLogger(t) + s = NewEvaluator(logger, store) + ) + + store.On("GetEvaluationRules", mock.Anything, storage.NewResource("", "foo")).Return( + []*storage.EvaluationRule{ + { + ID: "1", + FlagKey: "foo", + Rank: 0, + Segments: map[string]*storage.EvaluationSegment{ + "bar": { + SegmentKey: "bar", + MatchType: flipt.MatchType_ALL_MATCH_TYPE, + Constraints: []storage.EvaluationConstraint{ + { + ID: "2", + Type: flipt.ComparisonType_STRING_COMPARISON_TYPE, + Property: "bar", + Operator: flipt.OpEQ, + Value: "baz", + }, + }, + }, + }, + }, + }, nil) + + store.On("GetEvaluationDistributions", mock.Anything, storage.NewID("1")).Return([]*storage.EvaluationDistribution{}, nil) + + resp, err := s.Evaluate(context.TODO(), enabledFlagWithDefaultVariant, &evaluation.EvaluationRequest{ + FlagKey: "foo", + EntityId: "1", + Context: map[string]string{ + "bar": "baz", + }, + }) + + assert.NoError(t, err) + assert.NotNil(t, resp) + assert.Equal(t, "foo", resp.FlagKey) + assert.True(t, resp.Match) + assert.Equal(t, "bar", resp.SegmentKey) + assert.Equal(t, "bar", resp.Value) + assert.Equal(t, `{ "bar": "baz" }`, resp.Attachment) + assert.Equal(t, flipt.EvaluationReason_MATCH_EVALUATION_REASON, resp.Reason) +} + func TestEvaluator_MatchAll_MultipleSegments(t *testing.T) { var ( store = &evaluationStoreMock{} @@ -1415,6 +1530,76 @@ func TestEvaluator_DistributionNotMatched(t *testing.T) { assert.False(t, resp.Match, "distribution not matched") } +func TestEvaluator_DistributionNotMatched_DefaultVariant(t *testing.T) { + var ( + store = &evaluationStoreMock{} + logger = zaptest.NewLogger(t) + s = NewEvaluator(logger, store) + ) + + store.On("GetEvaluationRules", mock.Anything, storage.NewResource("", "foo")).Return( + []*storage.EvaluationRule{ + { + ID: "1", + FlagKey: "foo", + Rank: 0, + Segments: map[string]*storage.EvaluationSegment{ + "bar": { + SegmentKey: "bar", + MatchType: flipt.MatchType_ALL_MATCH_TYPE, + Constraints: []storage.EvaluationConstraint{ + // constraint: bar (string) == baz + { + ID: "2", + Type: flipt.ComparisonType_STRING_COMPARISON_TYPE, + Property: "bar", + Operator: flipt.OpEQ, + Value: "baz", + }, + // constraint: admin (bool) == true + { + ID: "3", + Type: flipt.ComparisonType_BOOLEAN_COMPARISON_TYPE, + Property: "admin", + Operator: flipt.OpTrue, + }, + }, + }, + }, + }, + }, nil) + + store.On("GetEvaluationDistributions", mock.Anything, storage.NewID("1")).Return( + []*storage.EvaluationDistribution{ + { + ID: "4", + RuleID: "1", + VariantID: "5", + Rollout: 10, + VariantKey: "boz", + VariantAttachment: `{"key":"value"}`, + }, + }, nil) + + resp, err := s.Evaluate(context.TODO(), enabledFlagWithDefaultVariant, &evaluation.EvaluationRequest{ + FlagKey: "foo", + EntityId: "123", + Context: map[string]string{ + "bar": "baz", + "admin": "true", + }, + }) + + assert.NoError(t, err) + assert.NotNil(t, resp) + assert.Equal(t, "foo", resp.FlagKey) + + assert.False(t, resp.Match, "distribution not matched") + assert.Equal(t, "bar", resp.Value) + assert.Equal(t, `{ "bar": "baz" }`, resp.Attachment) + assert.Equal(t, flipt.EvaluationReason_DEFAULT_EVALUATION_REASON, resp.Reason) +} + func TestEvaluator_MatchAll_SingleVariantDistribution(t *testing.T) { var ( store = &evaluationStoreMock{} @@ -1940,6 +2125,57 @@ func TestEvaluator_MatchAny_NoVariants_NoDistributions(t *testing.T) { } } +func TestEvaluator_MatchAny_NoDistributions_DefaultVariant(t *testing.T) { + var ( + store = &evaluationStoreMock{} + logger = zaptest.NewLogger(t) + s = NewEvaluator(logger, store) + ) + + store.On("GetEvaluationRules", mock.Anything, storage.NewResource("", "foo")).Return( + []*storage.EvaluationRule{ + { + ID: "1", + FlagKey: "foo", + Rank: 0, + Segments: map[string]*storage.EvaluationSegment{ + "bar": { + SegmentKey: "bar", + MatchType: flipt.MatchType_ANY_MATCH_TYPE, + Constraints: []storage.EvaluationConstraint{ + { + ID: "2", + Type: flipt.ComparisonType_STRING_COMPARISON_TYPE, + Property: "bar", + Operator: flipt.OpEQ, + Value: "baz", + }, + }, + }, + }, + }, + }, nil) + + store.On("GetEvaluationDistributions", mock.Anything, storage.NewID("1")).Return([]*storage.EvaluationDistribution{}, nil) + + resp, err := s.Evaluate(context.TODO(), enabledFlagWithDefaultVariant, &evaluation.EvaluationRequest{ + FlagKey: "foo", + EntityId: "1", + Context: map[string]string{ + "bar": "baz", + }, + }) + + assert.NoError(t, err) + assert.NotNil(t, resp) + assert.Equal(t, "foo", resp.FlagKey) + assert.True(t, resp.Match) + assert.Equal(t, "bar", resp.SegmentKey) + assert.Equal(t, "bar", resp.Value) + assert.Equal(t, `{ "bar": "baz" }`, resp.Attachment) + assert.Equal(t, flipt.EvaluationReason_MATCH_EVALUATION_REASON, resp.Reason) +} + func TestEvaluator_MatchAny_SingleVariantDistribution(t *testing.T) { var ( store = &evaluationStoreMock{} diff --git a/internal/server/middleware/grpc/middleware.go b/internal/server/middleware/grpc/middleware.go index 7ae63ef292..e21e2eea5e 100644 --- a/internal/server/middleware/grpc/middleware.go +++ b/internal/server/middleware/grpc/middleware.go @@ -319,11 +319,11 @@ func AuditEventUnaryInterceptor(logger *zap.Logger, eventPairChecker audit.Event // x-flipt-accept-server-version represents the maximum version of the flipt server that the client can handle. const fliptAcceptServerVersionHeaderKey = "x-flipt-accept-server-version" -type fliptServerVersionContextKey struct{} +type fliptAcceptServerVersionContextKey struct{} // WithFliptAcceptServerVersion sets the flipt version in the context. func WithFliptAcceptServerVersion(ctx context.Context, version semver.Version) context.Context { - return context.WithValue(ctx, fliptServerVersionContextKey{}, version) + return context.WithValue(ctx, fliptAcceptServerVersionContextKey{}, version) } // The last version that does not support the x-flipt-accept-server-version header. @@ -331,7 +331,7 @@ var preFliptAcceptServerVersion = semver.MustParse("1.37.1") // FliptAcceptServerVersionFromContext returns the flipt-accept-server-version from the context if it exists or the default version. func FliptAcceptServerVersionFromContext(ctx context.Context) semver.Version { - v, ok := ctx.Value(fliptServerVersionContextKey{}).(semver.Version) + v, ok := ctx.Value(fliptAcceptServerVersionContextKey{}).(semver.Version) if !ok { return preFliptAcceptServerVersion } diff --git a/internal/storage/fs/snapshot.go b/internal/storage/fs/snapshot.go index ddf2b0008c..568d1ce36c 100644 --- a/internal/storage/fs/snapshot.go +++ b/internal/storage/fs/snapshot.go @@ -144,14 +144,7 @@ func SnapshotFromPaths(logger *zap.Logger, ffs fs.FS, paths []string, opts ...co // SnapshotFromFiles constructs a StoreSnapshot from the provided slice // of fs.File implementations. func SnapshotFromFiles(logger *zap.Logger, files []fs.File, opts ...containers.Option[SnapshotOption]) (*Snapshot, error) { - now := flipt.Now() - s := Snapshot{ - ns: map[string]*namespace{ - defaultNs: newNamespace("default", "Default", now), - }, - evalDists: map[string][]*storage.EvaluationDistribution{}, - now: now, - } + s := newSnapshot() var so SnapshotOption containers.ApplyAll(&so, WithFileInfoEtag()) @@ -178,7 +171,7 @@ func SnapshotFromFiles(logger *zap.Logger, files []fs.File, opts ...containers.O } } - return &s, nil + return s, nil } // WalkDocuments walks all the Flipt feature documents found in the target fs.FS @@ -215,6 +208,17 @@ func WalkDocuments(logger *zap.Logger, src fs.FS, fn func(*ext.Document) error) return nil } +func newSnapshot() *Snapshot { + now := flipt.Now() + return &Snapshot{ + ns: map[string]*namespace{ + defaultNs: newNamespace("default", "Default", now), + }, + evalDists: map[string][]*storage.EvaluationDistribution{}, + now: now, + } +} + // documentsFromFile parses and validates a document from a single fs.File instance func documentsFromFile(fi fs.File, opts SnapshotOption) ([]*ext.Document, error) { validator, err := validation.NewFeaturesValidator(opts.validatorOption...) @@ -363,7 +367,7 @@ func (ss *Snapshot) addDoc(doc *ext.Document) error { return err } - flag.Variants = append(flag.Variants, &flipt.Variant{ + variant := &flipt.Variant{ Id: uuid.Must(uuid.NewV4()).String(), NamespaceKey: doc.Namespace, Key: v.Key, @@ -372,7 +376,13 @@ func (ss *Snapshot) addDoc(doc *ext.Document) error { Attachment: string(attachment), CreatedAt: ss.now, UpdatedAt: ss.now, - }) + } + + flag.Variants = append(flag.Variants, variant) + + if v.Default { + flag.DefaultVariant = variant + } } ns.flags[f.Key] = flag diff --git a/internal/storage/fs/testdata/valid/implicit_index/prod/features.yml b/internal/storage/fs/testdata/valid/implicit_index/prod/features.yml index ead0e2e365..4fa9af66f3 100644 --- a/internal/storage/fs/testdata/valid/implicit_index/prod/features.yml +++ b/internal/storage/fs/testdata/valid/implicit_index/prod/features.yml @@ -7,6 +7,7 @@ flags: variants: - key: prod-variant name: Prod Variant + default: true attachment: pi: 3.141 happy: true @@ -34,14 +35,14 @@ flags: description: Boolean Flag Description enabled: false rollouts: - - description: enabled for segment2 - segment: - key: segment2 - value: true - - description: enabled for 50% - threshold: - percentage: 50 - value: true + - description: enabled for segment2 + segment: + key: segment2 + value: true + - description: enabled for 50% + threshold: + percentage: 50 + value: true segments: - key: segment2 name: segment2 diff --git a/internal/storage/sql/common/flag.go b/internal/storage/sql/common/flag.go index f26248c3f6..00787240b5 100644 --- a/internal/storage/sql/common/flag.go +++ b/internal/storage/sql/common/flag.go @@ -36,12 +36,13 @@ func emptyAsNil(str string) *string { // GetFlag gets a flag with variants by key func (s *Store) GetFlag(ctx context.Context, p storage.ResourceRequest) (*flipt.Flag, error) { var ( - createdAt fliptsql.Timestamp - updatedAt fliptsql.Timestamp + createdAt fliptsql.Timestamp + updatedAt fliptsql.Timestamp + defaultVariantId sql.NullString flag = &flipt.Flag{} - err = s.builder.Select("namespace_key, \"key\", \"type\", name, description, enabled, created_at, updated_at"). + err = s.builder.Select("namespace_key, \"key\", \"type\", name, description, enabled, created_at, updated_at, default_variant_id"). From("flags"). Where(sq.Eq{"namespace_key": p.Namespace(), "\"key\"": p.Key}). QueryRowContext(ctx). @@ -53,7 +54,8 @@ func (s *Store) GetFlag(ctx context.Context, p storage.ResourceRequest) (*flipt. &flag.Description, &flag.Enabled, &createdAt, - &updatedAt) + &updatedAt, + &defaultVariantId) ) if err != nil { @@ -105,6 +107,7 @@ func (s *Store) GetFlag(ctx context.Context, p storage.ResourceRequest) (*flipt. variant.CreatedAt = createdAt.Timestamp variant.UpdatedAt = updatedAt.Timestamp + if attachment.Valid { compactedAttachment, err := compactJSONString(attachment.String) if err != nil { @@ -113,6 +116,10 @@ func (s *Store) GetFlag(ctx context.Context, p storage.ResourceRequest) (*flipt. variant.Attachment = compactedAttachment } + if defaultVariantId.Valid && variant.Id == defaultVariantId.String { + flag.DefaultVariant = &variant + } + flag.Variants = append(flag.Variants, &variant) } @@ -131,13 +138,18 @@ type optionalVariant struct { UpdatedAt fliptsql.NullableTimestamp } +type flagWithDefaultVariant struct { + *flipt.Flag + DefaultVariantId sql.NullString +} + // ListFlags lists all flags with variants func (s *Store) ListFlags(ctx context.Context, req *storage.ListRequest[storage.NamespaceRequest]) (storage.ResultSet[*flipt.Flag], error) { var ( flags []*flipt.Flag results = storage.ResultSet[*flipt.Flag]{} - query = s.builder.Select("namespace_key, \"key\", \"type\", name, description, enabled, created_at, updated_at"). + query = s.builder.Select("namespace_key, \"key\", \"type\", name, description, enabled, created_at, updated_at, default_variant_id"). From("flags"). Where(sq.Eq{"namespace_key": req.Predicate.Namespace()}). OrderBy(fmt.Sprintf("created_at %s", req.QueryParams.Order)) @@ -174,13 +186,14 @@ func (s *Store) ListFlags(ctx context.Context, req *storage.ListRequest[storage. }() // keep track of flags so we can associated variants in second query. - flagsByKey := make(map[string]*flipt.Flag) + flagsByKey := make(map[string]*flagWithDefaultVariant) for rows.Next() { var ( flag = &flipt.Flag{} - fCreatedAt fliptsql.Timestamp - fUpdatedAt fliptsql.Timestamp + fCreatedAt fliptsql.Timestamp + fUpdatedAt fliptsql.Timestamp + fDefaultVariantId sql.NullString ) if err := rows.Scan( @@ -191,7 +204,9 @@ func (s *Store) ListFlags(ctx context.Context, req *storage.ListRequest[storage. &flag.Description, &flag.Enabled, &fCreatedAt, - &fUpdatedAt); err != nil { + &fUpdatedAt, + &fDefaultVariantId, + ); err != nil { return results, err } @@ -199,7 +214,7 @@ func (s *Store) ListFlags(ctx context.Context, req *storage.ListRequest[storage. flag.UpdatedAt = fUpdatedAt.Timestamp flags = append(flags, flag) - flagsByKey[flag.Key] = flag + flagsByKey[flag.Key] = &flagWithDefaultVariant{Flag: flag, DefaultVariantId: fDefaultVariantId} } if err := rows.Err(); err != nil { @@ -234,7 +249,7 @@ func (s *Store) ListFlags(ctx context.Context, req *storage.ListRequest[storage. return results, nil } -func (s *Store) setVariants(ctx context.Context, namespaceKey string, flagsByKey map[string]*flipt.Flag) error { +func (s *Store) setVariants(ctx context.Context, namespaceKey string, flagsByKey map[string]*flagWithDefaultVariant) error { allFlagKeys := make([]string, 0, len(flagsByKey)) for k := range flagsByKey { allFlagKeys = append(allFlagKeys, k) @@ -277,7 +292,7 @@ func (s *Store) setVariants(ctx context.Context, namespaceKey string, flagsByKey } if flag, ok := flagsByKey[variant.FlagKey.String]; ok { - flag.Variants = append(flag.Variants, &flipt.Variant{ + v := &flipt.Variant{ Id: variant.Id.String, NamespaceKey: variant.NamespaceKey.String, Key: variant.Key.String, @@ -287,7 +302,13 @@ func (s *Store) setVariants(ctx context.Context, namespaceKey string, flagsByKey Attachment: variant.Attachment.String, CreatedAt: vCreatedAt.Timestamp, UpdatedAt: vUpdatedAt.Timestamp, - }) + } + + flag.Variants = append(flag.Variants, v) + + if flag.DefaultVariantId.Valid && variant.Id.String == flag.DefaultVariantId.String { + flag.DefaultVariant = v + } } } @@ -370,11 +391,36 @@ func (s *Store) UpdateFlag(ctx context.Context, r *flipt.UpdateFlagRequest) (_ * r.NamespaceKey = storage.DefaultNamespace } + // if default variant is set, check that the variant and flag exist in the same namespace + if r.DefaultVariantId != "" { + var count uint64 + + if err := s.builder.Select("COUNT(id)"). + From("variants"). + Where(sq.Eq{"id": r.DefaultVariantId, "namespace_key": r.NamespaceKey, "flag_key": r.Key}). + QueryRowContext(ctx). + Scan(&count); err != nil { + return nil, err + } + + if count != 1 { + return nil, errs.ErrInvalidf(`variant %q not found for flag "%s/%s"`, r.DefaultVariantId, r.NamespaceKey, r.Key) + } + } + query := s.builder.Update("flags"). Set("name", r.Name). Set("description", r.Description). Set("enabled", r.Enabled). - Set("updated_at", &fliptsql.Timestamp{Timestamp: flipt.Now()}). + Set("updated_at", &fliptsql.Timestamp{Timestamp: flipt.Now()}) + + if r.DefaultVariantId != "" { + query = query.Set("default_variant_id", r.DefaultVariantId) + } else { + query = query.Set("default_variant_id", nil) + } + + query = query. Where(sq.And{sq.Eq{"namespace_key": r.NamespaceKey}, sq.Eq{"\"key\"": r.Key}}) res, err := query.ExecContext(ctx) diff --git a/internal/storage/sql/flag_test.go b/internal/storage/sql/flag_test.go index bb54566ce0..9b705eb6f5 100644 --- a/internal/storage/sql/flag_test.go +++ b/internal/storage/sql/flag_test.go @@ -644,6 +644,159 @@ func (s *DBTestSuite) TestUpdateFlagNamespace_NotFound() { assert.EqualError(t, err, fmt.Sprintf("flag \"%s/foo\" not found", s.namespace)) } +func (s *DBTestSuite) TestUpdateFlag_DefaultVariant() { + t := s.T() + + t.Run("update flag with default variant", func(t *testing.T) { + flag, err := s.store.CreateFlag(context.TODO(), &flipt.CreateFlagRequest{ + Key: t.Name(), + Name: "foo", + Description: "bar", + Enabled: true, + }) + + require.NoError(t, err) + + variant, err := s.store.CreateVariant(context.TODO(), &flipt.CreateVariantRequest{ + FlagKey: flag.Key, + Key: t.Name(), + Name: "foo", + Description: "bar", + Attachment: `{"key":"value"}`, + }) + + require.NoError(t, err) + assert.NotNil(t, variant) + + _, err = s.store.UpdateFlag(context.TODO(), &flipt.UpdateFlagRequest{ + Key: flag.Key, + Name: flag.Name, + Description: "foobar", + Enabled: true, + DefaultVariantId: variant.Id, + }) + + require.NoError(t, err) + + // get the flag again + flag, err = s.store.GetFlag(context.TODO(), storage.NewResource(storage.DefaultNamespace, flag.Key)) + + require.NoError(t, err) + assert.NotNil(t, flag) + assert.Equal(t, variant.Id, flag.DefaultVariant.Id) + assert.Equal(t, variant.Key, flag.DefaultVariant.Key) + assert.Equal(t, variant.Name, flag.DefaultVariant.Name) + assert.Equal(t, variant.Description, flag.DefaultVariant.Description) + assert.Equal(t, variant.Attachment, flag.DefaultVariant.Attachment) + }) + + t.Run("update flag with default variant not found", func(t *testing.T) { + flag, err := s.store.CreateFlag(context.TODO(), &flipt.CreateFlagRequest{ + Key: t.Name(), + Name: "foo", + Description: "bar", + Enabled: true, + }) + + require.NoError(t, err) + + _, err = s.store.UpdateFlag(context.TODO(), &flipt.UpdateFlagRequest{ + Key: flag.Key, + Name: flag.Name, + Description: "foobar", + Enabled: true, + DefaultVariantId: "non-existent", + }) + + assert.EqualError(t, err, "variant \"non-existent\" not found for flag \"default/TestDBTestSuite/TestUpdateFlag_DefaultVariant/update_flag_with_default_variant_not_found\"") + }) + + t.Run("update flag with variant from different flag", func(t *testing.T) { + flag, err := s.store.CreateFlag(context.TODO(), &flipt.CreateFlagRequest{ + Key: t.Name(), + Name: "foo", + Description: "bar", + Enabled: true, + }) + + require.NoError(t, err) + + flag2, err := s.store.CreateFlag(context.TODO(), &flipt.CreateFlagRequest{ + Key: fmt.Sprintf("%s_two", t.Name()), + Name: "foo", + Description: "bar", + Enabled: true, + }) + + require.NoError(t, err) + + variant, err := s.store.CreateVariant(context.TODO(), &flipt.CreateVariantRequest{ + FlagKey: flag2.Key, + Key: t.Name(), + Name: "foo", + Description: "bar", + Attachment: `{"key":"value"}`, + }) + + require.NoError(t, err) + + _, err = s.store.UpdateFlag(context.TODO(), &flipt.UpdateFlagRequest{ + Key: flag.Key, + Name: flag.Name, + Description: "foobar", + Enabled: true, + DefaultVariantId: variant.Id, + }) + + assert.EqualError(t, err, fmt.Sprintf("variant \"%s\" not found for flag \"%s/%s\"", variant.Id, "default", flag.Key)) + }) + + t.Run("update flag with default variant in different namespace", func(t *testing.T) { + + flag, err := s.store.CreateFlag(context.TODO(), &flipt.CreateFlagRequest{ + NamespaceKey: s.namespace, + Key: t.Name(), + Name: "foo", + Description: "bar", + Enabled: true, + }) + + require.NoError(t, err) + + variant, err := s.store.CreateVariant(context.TODO(), &flipt.CreateVariantRequest{ + NamespaceKey: s.namespace, + FlagKey: flag.Key, + Key: t.Name(), + Name: "foo", + Description: "bar", + Attachment: `{"key":"value"}`, + }) + + require.NoError(t, err) + + // flag in default namespace + flag2, err := s.store.CreateFlag(context.TODO(), &flipt.CreateFlagRequest{ + Key: t.Name(), + Name: "foo", + Description: "bar", + Enabled: true, + }) + + require.NoError(t, err) + + // try to update flag in non-default namespace with default variant from default namespace + _, err = s.store.UpdateFlag(context.TODO(), &flipt.UpdateFlagRequest{ + Key: flag2.Key, + Name: flag2.Name, + Description: flag2.Description, + Enabled: true, + DefaultVariantId: variant.Id, + }) + + assert.EqualError(t, err, fmt.Sprintf("variant \"%s\" not found for flag \"%s/%s\"", variant.Id, "default", flag2.Key)) + }) +} + func (s *DBTestSuite) TestDeleteFlag() { t := s.T() @@ -1519,6 +1672,52 @@ func (s *DBTestSuite) TestDeleteVariantNamespace_NotFound() { require.NoError(t, err) } +func (s *DBTestSuite) TestDeleteVariant_DefaultVariant() { + t := s.T() + + flag, err := s.store.CreateFlag(context.TODO(), &flipt.CreateFlagRequest{ + Key: t.Name(), + Name: "foo", + Description: "bar", + Enabled: true, + }) + + require.NoError(t, err) + assert.NotNil(t, flag) + + variant, err := s.store.CreateVariant(context.TODO(), &flipt.CreateVariantRequest{ + FlagKey: flag.Key, + Key: "foo", + Name: "foo", + Description: "bar", + }) + + require.NoError(t, err) + assert.NotNil(t, variant) + + _, err = s.store.UpdateFlag(context.TODO(), &flipt.UpdateFlagRequest{ + Key: flag.Key, + Name: flag.Name, + Description: flag.Description, + Enabled: true, + DefaultVariantId: variant.Id, + }) + + require.NoError(t, err) + + err = s.store.DeleteVariant(context.TODO(), &flipt.DeleteVariantRequest{FlagKey: variant.FlagKey, Id: variant.Id}) + require.NoError(t, err) + + // get the flag again + flag, err = s.store.GetFlag(context.TODO(), storage.NewResource(storage.DefaultNamespace, flag.Key)) + + require.NoError(t, err) + assert.NotNil(t, flag) + + assert.Empty(t, flag.Variants) + assert.Nil(t, flag.DefaultVariant) +} + func BenchmarkListFlags(b *testing.B) { s := new(DBTestSuite) t := &testing.T{} diff --git a/internal/storage/sql/migrator.go b/internal/storage/sql/migrator.go index dad7002a08..8e3a766df2 100644 --- a/internal/storage/sql/migrator.go +++ b/internal/storage/sql/migrator.go @@ -19,11 +19,11 @@ import ( ) var expectedVersions = map[Driver]uint{ - SQLite: 12, - LibSQL: 12, // libsql driver uses the same migrations as sqlite3 - Postgres: 13, - MySQL: 12, - CockroachDB: 10, + SQLite: 13, + LibSQL: 13, // libsql driver uses the same migrations as sqlite3 + Postgres: 14, + MySQL: 13, + CockroachDB: 11, Clickhouse: 3, } diff --git a/internal/storage/sql/mysql/mysql.go b/internal/storage/sql/mysql/mysql.go index 5d65758df1..c413d199a3 100644 --- a/internal/storage/sql/mysql/mysql.go +++ b/internal/storage/sql/mysql/mysql.go @@ -16,8 +16,8 @@ import ( ) const ( - constraintForeignKeyErrCode uint16 = 1452 - constraintUniqueErrCode uint16 = 1062 + constraintForeignKeyErr uint16 = 1452 + constraintUniqueErr uint16 = 1062 ) var _ storage.Store = &Store{} @@ -42,7 +42,7 @@ func (s *Store) CreateNamespace(ctx context.Context, r *flipt.CreateNamespaceReq if err != nil { var merr *mysql.MySQLError - if errors.As(err, &merr) && merr.Number == constraintUniqueErrCode { + if errors.As(err, &merr) && merr.Number == constraintUniqueErr { return nil, errs.ErrInvalidf("namespace %q is not unique", r.Key) } @@ -60,9 +60,9 @@ func (s *Store) CreateFlag(ctx context.Context, r *flipt.CreateFlagRequest) (*fl if errors.As(err, &merr) { switch merr.Number { - case constraintForeignKeyErrCode: + case constraintForeignKeyErr: return nil, errs.ErrNotFoundf("namespace %q", r.NamespaceKey) - case constraintUniqueErrCode: + case constraintUniqueErr: return nil, errs.ErrInvalidf(`flag "%s/%s" is not unique`, r.NamespaceKey, r.Key) } } @@ -73,6 +73,26 @@ func (s *Store) CreateFlag(ctx context.Context, r *flipt.CreateFlagRequest) (*fl return flag, nil } +func (s *Store) UpdateFlag(ctx context.Context, r *flipt.UpdateFlagRequest) (*flipt.Flag, error) { + flag, err := s.Store.UpdateFlag(ctx, r) + + if err != nil { + var merr *mysql.MySQLError + + if errors.As(err, &merr) && merr.Number == constraintForeignKeyErr { + if r.DefaultVariantId != "" { + return nil, errs.ErrInvalidf(`variant %q not found for flag "%s/%s"`, r.DefaultVariantId, r.NamespaceKey, r.Key) + } + + return nil, errs.ErrInvalidf(`flag "%s/%s" not found`, r.NamespaceKey, r.Key) + } + + return nil, err + } + + return flag, nil +} + func (s *Store) CreateVariant(ctx context.Context, r *flipt.CreateVariantRequest) (*flipt.Variant, error) { variant, err := s.Store.CreateVariant(ctx, r) @@ -81,9 +101,9 @@ func (s *Store) CreateVariant(ctx context.Context, r *flipt.CreateVariantRequest if errors.As(err, &merr) { switch merr.Number { - case constraintForeignKeyErrCode: + case constraintForeignKeyErr: return nil, errs.ErrNotFoundf(`flag "%s/%s"`, r.NamespaceKey, r.FlagKey) - case constraintUniqueErrCode: + case constraintUniqueErr: return nil, errs.ErrInvalidf(`variant %q is not unique for flag "%s/%s"`, r.Key, r.NamespaceKey, r.FlagKey) } } @@ -100,7 +120,7 @@ func (s *Store) UpdateVariant(ctx context.Context, r *flipt.UpdateVariantRequest if err != nil { var merr *mysql.MySQLError - if errors.As(err, &merr) && merr.Number == constraintUniqueErrCode { + if errors.As(err, &merr) && merr.Number == constraintUniqueErr { return nil, errs.ErrInvalidf(`variant %q is not unique for flag "%s/%s"`, r.Key, r.NamespaceKey, r.FlagKey) } @@ -118,9 +138,9 @@ func (s *Store) CreateSegment(ctx context.Context, r *flipt.CreateSegmentRequest if errors.As(err, &merr) { switch merr.Number { - case constraintForeignKeyErrCode: + case constraintForeignKeyErr: return nil, errs.ErrNotFoundf("namespace %q", r.NamespaceKey) - case constraintUniqueErrCode: + case constraintUniqueErr: return nil, errs.ErrInvalidf(`segment "%s/%s" is not unique`, r.NamespaceKey, r.Key) } } @@ -137,7 +157,7 @@ func (s *Store) CreateConstraint(ctx context.Context, r *flipt.CreateConstraintR if err != nil { var merr *mysql.MySQLError - if errors.As(err, &merr) && merr.Number == constraintForeignKeyErrCode { + if errors.As(err, &merr) && merr.Number == constraintForeignKeyErr { return nil, errs.ErrNotFoundf(`segment "%s/%s"`, r.NamespaceKey, r.SegmentKey) } @@ -153,7 +173,7 @@ func (s *Store) CreateRollout(ctx context.Context, r *flipt.CreateRolloutRequest if err != nil { var merr *mysql.MySQLError - if errors.As(err, &merr) && merr.Number == constraintForeignKeyErrCode { + if errors.As(err, &merr) && merr.Number == constraintForeignKeyErr { if segment := r.GetSegment(); segment != nil { return nil, errs.ErrNotFoundf(`flag "%s/%s or segment %s"`, r.NamespaceKey, r.FlagKey, segment.SegmentKey) } @@ -172,7 +192,7 @@ func (s *Store) CreateRule(ctx context.Context, r *flipt.CreateRuleRequest) (*fl if err != nil { var merr *mysql.MySQLError - if errors.As(err, &merr) && merr.Number == constraintForeignKeyErrCode { + if errors.As(err, &merr) && merr.Number == constraintForeignKeyErr { return nil, errs.ErrNotFoundf(`flag "%s/%s" or segment "%s/%s"`, r.NamespaceKey, r.FlagKey, r.NamespaceKey, r.SegmentKey) } @@ -188,7 +208,7 @@ func (s *Store) UpdateRule(ctx context.Context, r *flipt.UpdateRuleRequest) (*fl if err != nil { var merr *mysql.MySQLError - if errors.As(err, &merr) && merr.Number == constraintForeignKeyErrCode { + if errors.As(err, &merr) && merr.Number == constraintForeignKeyErr { return nil, errs.ErrNotFoundf(`rule "%s/%s"`, r.NamespaceKey, r.Id) } @@ -204,7 +224,7 @@ func (s *Store) CreateDistribution(ctx context.Context, r *flipt.CreateDistribut if err != nil { var merr *mysql.MySQLError - if errors.As(err, &merr) && merr.Number == constraintForeignKeyErrCode { + if errors.As(err, &merr) && merr.Number == constraintForeignKeyErr { return nil, errs.ErrNotFoundf("variant %q, rule %q, flag %q in namespace %q", r.VariantId, r.RuleId, r.FlagKey, r.NamespaceKey) } diff --git a/internal/storage/sql/postgres/postgres.go b/internal/storage/sql/postgres/postgres.go index 0a48d8ef5e..f56dc94a8d 100644 --- a/internal/storage/sql/postgres/postgres.go +++ b/internal/storage/sql/postgres/postgres.go @@ -73,6 +73,26 @@ func (s *Store) CreateFlag(ctx context.Context, r *flipt.CreateFlagRequest) (*fl return flag, nil } +func (s *Store) UpdateFlag(ctx context.Context, r *flipt.UpdateFlagRequest) (*flipt.Flag, error) { + flag, err := s.Store.UpdateFlag(ctx, r) + + if err != nil { + var perr *pgconn.PgError + + if errors.As(err, &perr) && perr.Code == constraintForeignKeyErr { + if r.DefaultVariantId != "" { + return nil, errs.ErrInvalidf(`variant %q not found for flag "%s/%s"`, r.DefaultVariantId, r.NamespaceKey, r.Key) + } + + return nil, errs.ErrInvalidf(`flag "%s/%s" not found`, r.NamespaceKey, r.Key) + } + + return nil, err + } + + return flag, nil +} + func (s *Store) CreateVariant(ctx context.Context, r *flipt.CreateVariantRequest) (*flipt.Variant, error) { variant, err := s.Store.CreateVariant(ctx, r) diff --git a/internal/storage/sql/sqlite/sqlite.go b/internal/storage/sql/sqlite/sqlite.go index 310b12cdf4..f26781c744 100644 --- a/internal/storage/sql/sqlite/sqlite.go +++ b/internal/storage/sql/sqlite/sqlite.go @@ -70,6 +70,26 @@ func (s *Store) CreateFlag(ctx context.Context, r *flipt.CreateFlagRequest) (*fl return flag, nil } +func (s *Store) UpdateFlag(ctx context.Context, r *flipt.UpdateFlagRequest) (*flipt.Flag, error) { + flag, err := s.Store.UpdateFlag(ctx, r) + + if err != nil { + var serr sqlite3.Error + + if errors.As(err, &serr) && serr.ExtendedCode == sqlite3.ErrConstraintForeignKey { + if r.DefaultVariantId != "" { + return nil, errs.ErrInvalidf(`variant %q not found for flag "%s/%s"`, r.DefaultVariantId, r.NamespaceKey, r.Key) + } + + return nil, errs.ErrInvalidf(`flag "%s/%s" not found`, r.NamespaceKey, r.Key) + } + + return nil, err + } + + return flag, nil +} + func (s *Store) CreateVariant(ctx context.Context, r *flipt.CreateVariantRequest) (*flipt.Variant, error) { variant, err := s.Store.CreateVariant(ctx, r) diff --git a/rpc/flipt/evaluation/evaluation.pb.go b/rpc/flipt/evaluation/evaluation.pb.go index d862aa5c14..dfa03c7d82 100644 --- a/rpc/flipt/evaluation/evaluation.pb.go +++ b/rpc/flipt/evaluation/evaluation.pb.go @@ -1387,26 +1387,90 @@ func (x *EvaluationSegment) GetConstraints() []*EvaluationConstraint { return nil } +type EvaluationVariant struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + Attachment string `protobuf:"bytes,3,opt,name=attachment,proto3" json:"attachment,omitempty"` +} + +func (x *EvaluationVariant) Reset() { + *x = EvaluationVariant{} + if protoimpl.UnsafeEnabled { + mi := &file_evaluation_evaluation_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EvaluationVariant) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EvaluationVariant) ProtoMessage() {} + +func (x *EvaluationVariant) ProtoReflect() protoreflect.Message { + mi := &file_evaluation_evaluation_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EvaluationVariant.ProtoReflect.Descriptor instead. +func (*EvaluationVariant) Descriptor() ([]byte, []int) { + return file_evaluation_evaluation_proto_rawDescGZIP(), []int{12} +} + +func (x *EvaluationVariant) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *EvaluationVariant) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *EvaluationVariant) GetAttachment() string { + if x != nil { + return x.Attachment + } + return "" +} + type EvaluationFlag struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - Enabled bool `protobuf:"varint,4,opt,name=enabled,proto3" json:"enabled,omitempty"` - Type EvaluationFlagType `protobuf:"varint,5,opt,name=type,proto3,enum=flipt.evaluation.EvaluationFlagType" json:"type,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` - Rules []*EvaluationRule `protobuf:"bytes,8,rep,name=rules,proto3" json:"rules,omitempty"` - Rollouts []*EvaluationRollout `protobuf:"bytes,9,rep,name=rollouts,proto3" json:"rollouts,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Enabled bool `protobuf:"varint,4,opt,name=enabled,proto3" json:"enabled,omitempty"` + Type EvaluationFlagType `protobuf:"varint,5,opt,name=type,proto3,enum=flipt.evaluation.EvaluationFlagType" json:"type,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + Rules []*EvaluationRule `protobuf:"bytes,8,rep,name=rules,proto3" json:"rules,omitempty"` + Rollouts []*EvaluationRollout `protobuf:"bytes,9,rep,name=rollouts,proto3" json:"rollouts,omitempty"` + DefaultVariant *EvaluationVariant `protobuf:"bytes,10,opt,name=default_variant,json=defaultVariant,proto3,oneof" json:"default_variant,omitempty"` } func (x *EvaluationFlag) Reset() { *x = EvaluationFlag{} if protoimpl.UnsafeEnabled { - mi := &file_evaluation_evaluation_proto_msgTypes[12] + mi := &file_evaluation_evaluation_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1419,7 +1483,7 @@ func (x *EvaluationFlag) String() string { func (*EvaluationFlag) ProtoMessage() {} func (x *EvaluationFlag) ProtoReflect() protoreflect.Message { - mi := &file_evaluation_evaluation_proto_msgTypes[12] + mi := &file_evaluation_evaluation_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1432,7 +1496,7 @@ func (x *EvaluationFlag) ProtoReflect() protoreflect.Message { // Deprecated: Use EvaluationFlag.ProtoReflect.Descriptor instead. func (*EvaluationFlag) Descriptor() ([]byte, []int) { - return file_evaluation_evaluation_proto_rawDescGZIP(), []int{12} + return file_evaluation_evaluation_proto_rawDescGZIP(), []int{13} } func (x *EvaluationFlag) GetKey() string { @@ -1498,6 +1562,13 @@ func (x *EvaluationFlag) GetRollouts() []*EvaluationRollout { return nil } +func (x *EvaluationFlag) GetDefaultVariant() *EvaluationVariant { + if x != nil { + return x.DefaultVariant + } + return nil +} + type EvaluationConstraint struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1513,7 +1584,7 @@ type EvaluationConstraint struct { func (x *EvaluationConstraint) Reset() { *x = EvaluationConstraint{} if protoimpl.UnsafeEnabled { - mi := &file_evaluation_evaluation_proto_msgTypes[13] + mi := &file_evaluation_evaluation_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1526,7 +1597,7 @@ func (x *EvaluationConstraint) String() string { func (*EvaluationConstraint) ProtoMessage() {} func (x *EvaluationConstraint) ProtoReflect() protoreflect.Message { - mi := &file_evaluation_evaluation_proto_msgTypes[13] + mi := &file_evaluation_evaluation_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1539,7 +1610,7 @@ func (x *EvaluationConstraint) ProtoReflect() protoreflect.Message { // Deprecated: Use EvaluationConstraint.ProtoReflect.Descriptor instead. func (*EvaluationConstraint) Descriptor() ([]byte, []int) { - return file_evaluation_evaluation_proto_rawDescGZIP(), []int{13} + return file_evaluation_evaluation_proto_rawDescGZIP(), []int{14} } func (x *EvaluationConstraint) GetId() string { @@ -1592,7 +1663,7 @@ type EvaluationRule struct { func (x *EvaluationRule) Reset() { *x = EvaluationRule{} if protoimpl.UnsafeEnabled { - mi := &file_evaluation_evaluation_proto_msgTypes[14] + mi := &file_evaluation_evaluation_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1605,7 +1676,7 @@ func (x *EvaluationRule) String() string { func (*EvaluationRule) ProtoMessage() {} func (x *EvaluationRule) ProtoReflect() protoreflect.Message { - mi := &file_evaluation_evaluation_proto_msgTypes[14] + mi := &file_evaluation_evaluation_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1618,7 +1689,7 @@ func (x *EvaluationRule) ProtoReflect() protoreflect.Message { // Deprecated: Use EvaluationRule.ProtoReflect.Descriptor instead. func (*EvaluationRule) Descriptor() ([]byte, []int) { - return file_evaluation_evaluation_proto_rawDescGZIP(), []int{14} + return file_evaluation_evaluation_proto_rawDescGZIP(), []int{15} } func (x *EvaluationRule) GetId() string { @@ -1667,7 +1738,7 @@ type EvaluationNamespace struct { func (x *EvaluationNamespace) Reset() { *x = EvaluationNamespace{} if protoimpl.UnsafeEnabled { - mi := &file_evaluation_evaluation_proto_msgTypes[15] + mi := &file_evaluation_evaluation_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1680,7 +1751,7 @@ func (x *EvaluationNamespace) String() string { func (*EvaluationNamespace) ProtoMessage() {} func (x *EvaluationNamespace) ProtoReflect() protoreflect.Message { - mi := &file_evaluation_evaluation_proto_msgTypes[15] + mi := &file_evaluation_evaluation_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1693,7 +1764,7 @@ func (x *EvaluationNamespace) ProtoReflect() protoreflect.Message { // Deprecated: Use EvaluationNamespace.ProtoReflect.Descriptor instead. func (*EvaluationNamespace) Descriptor() ([]byte, []int) { - return file_evaluation_evaluation_proto_rawDescGZIP(), []int{15} + return file_evaluation_evaluation_proto_rawDescGZIP(), []int{16} } func (x *EvaluationNamespace) GetKey() string { @@ -1715,7 +1786,7 @@ type EvaluationNamespaceSnapshot struct { func (x *EvaluationNamespaceSnapshot) Reset() { *x = EvaluationNamespaceSnapshot{} if protoimpl.UnsafeEnabled { - mi := &file_evaluation_evaluation_proto_msgTypes[16] + mi := &file_evaluation_evaluation_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1728,7 +1799,7 @@ func (x *EvaluationNamespaceSnapshot) String() string { func (*EvaluationNamespaceSnapshot) ProtoMessage() {} func (x *EvaluationNamespaceSnapshot) ProtoReflect() protoreflect.Message { - mi := &file_evaluation_evaluation_proto_msgTypes[16] + mi := &file_evaluation_evaluation_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1741,7 +1812,7 @@ func (x *EvaluationNamespaceSnapshot) ProtoReflect() protoreflect.Message { // Deprecated: Use EvaluationNamespaceSnapshot.ProtoReflect.Descriptor instead. func (*EvaluationNamespaceSnapshot) Descriptor() ([]byte, []int) { - return file_evaluation_evaluation_proto_rawDescGZIP(), []int{16} + return file_evaluation_evaluation_proto_rawDescGZIP(), []int{17} } func (x *EvaluationNamespaceSnapshot) GetNamespace() *EvaluationNamespace { @@ -1770,7 +1841,7 @@ type EvaluationNamespaceSnapshotRequest struct { func (x *EvaluationNamespaceSnapshotRequest) Reset() { *x = EvaluationNamespaceSnapshotRequest{} if protoimpl.UnsafeEnabled { - mi := &file_evaluation_evaluation_proto_msgTypes[17] + mi := &file_evaluation_evaluation_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1783,7 +1854,7 @@ func (x *EvaluationNamespaceSnapshotRequest) String() string { func (*EvaluationNamespaceSnapshotRequest) ProtoMessage() {} func (x *EvaluationNamespaceSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_evaluation_evaluation_proto_msgTypes[17] + mi := &file_evaluation_evaluation_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1796,7 +1867,7 @@ func (x *EvaluationNamespaceSnapshotRequest) ProtoReflect() protoreflect.Message // Deprecated: Use EvaluationNamespaceSnapshotRequest.ProtoReflect.Descriptor instead. func (*EvaluationNamespaceSnapshotRequest) Descriptor() ([]byte, []int) { - return file_evaluation_evaluation_proto_rawDescGZIP(), []int{17} + return file_evaluation_evaluation_proto_rawDescGZIP(), []int{18} } func (x *EvaluationNamespaceSnapshotRequest) GetKey() string { @@ -2006,175 +2077,187 @@ var file_evaluation_evaluation_proto_rawDesc = []byte{ 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x9b, 0x03, 0x0a, 0x0e, 0x45, - 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, - 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, + 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x55, 0x0a, 0x11, 0x45, 0x76, + 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, + 0x74, 0x22, 0x82, 0x04, 0x0a, 0x0e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x46, 0x6c, 0x61, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x46, 0x6c, 0x61, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, + 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x3f, + 0x0a, 0x08, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, + 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x12, + 0x51, 0x0a, 0x0f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, + 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x88, + 0x01, 0x01, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x22, 0xbe, 0x01, 0x0a, 0x14, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x48, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x61, 0x67, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x36, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, - 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, - 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x08, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, - 0x75, 0x74, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, 0x6c, 0x69, 0x70, + 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x61, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9d, 0x02, 0x0a, 0x0e, 0x45, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3f, 0x0a, 0x08, 0x73, 0x65, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x66, + 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, + 0x61, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x72, 0x61, 0x6e, 0x6b, 0x12, + 0x56, 0x0a, 0x10, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x08, - 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x22, 0xbe, 0x01, 0x0a, 0x14, 0x45, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x48, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x34, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, - 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, - 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9d, 0x02, 0x0a, 0x0e, 0x45, 0x76, - 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3f, 0x0a, 0x08, - 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, + 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0f, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x4e, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x72, 0x61, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x72, 0x61, 0x6e, - 0x6b, 0x12, 0x56, 0x0a, 0x10, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, - 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, - 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0f, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, - 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x4e, 0x0a, 0x0d, 0x64, 0x69, 0x73, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, - 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x27, 0x0a, 0x13, 0x45, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x22, 0x9a, 0x01, 0x0a, 0x1b, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x12, 0x43, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, - 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, - 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, - 0x54, 0x0a, 0x22, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2a, 0x92, 0x01, 0x0a, 0x10, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x19, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x4c, 0x41, - 0x47, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x1b, - 0x0a, 0x17, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x44, - 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x03, 0x2a, 0x63, 0x0a, 0x15, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, - 0x73, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x1f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x4e, 0x4f, 0x54, 0x5f, - 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x56, 0x41, 0x4c, - 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x01, 0x2a, - 0x88, 0x01, 0x0a, 0x16, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x20, 0x56, 0x41, - 0x52, 0x49, 0x41, 0x4e, 0x54, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, - 0x12, 0x24, 0x0a, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x45, 0x56, 0x41, 0x4c, - 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, - 0x4e, 0x53, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x02, 0x2a, 0x67, 0x0a, 0x15, 0x45, 0x76, - 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x52, - 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x18, 0x0a, - 0x14, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x48, 0x52, 0x45, 0x53, - 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x10, 0x02, 0x2a, 0x4e, 0x0a, 0x19, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x12, 0x17, 0x0a, 0x13, 0x4f, 0x52, 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4f, - 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x4e, 0x44, - 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, - 0x52, 0x10, 0x01, 0x2a, 0x54, 0x0a, 0x1a, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x4c, 0x4c, 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, - 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, - 0x16, 0x41, 0x4e, 0x59, 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x2a, 0x42, 0x0a, 0x12, 0x45, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x61, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x15, 0x0a, 0x11, 0x56, 0x41, 0x52, 0x49, 0x41, 0x4e, 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, - 0x4e, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x2a, 0x95, 0x02, - 0x0a, 0x22, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, - 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, - 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, - 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, - 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, - 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x43, 0x4f, + 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x27, 0x0a, 0x13, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x22, 0x9a, 0x01, 0x0a, 0x1b, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x12, 0x43, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x54, 0x0a, + 0x22, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x2a, 0x92, 0x01, 0x0a, 0x10, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x19, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, + 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x4c, 0x41, 0x47, 0x5f, + 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x46, + 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x03, 0x2a, 0x63, 0x0a, 0x15, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x12, 0x23, 0x0a, 0x1f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, + 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, + 0x55, 0x4e, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x01, 0x2a, 0x88, 0x01, + 0x0a, 0x16, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x20, 0x56, 0x41, 0x52, 0x49, + 0x41, 0x4e, 0x54, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, + 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x24, + 0x0a, 0x20, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x56, + 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x02, 0x2a, 0x67, 0x0a, 0x15, 0x45, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x52, 0x4f, 0x4c, + 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x53, + 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, + 0x4c, 0x44, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, + 0x02, 0x2a, 0x4e, 0x0a, 0x19, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x17, + 0x0a, 0x13, 0x4f, 0x52, 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4f, 0x50, 0x45, + 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x4e, 0x44, 0x5f, 0x53, + 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, + 0x01, 0x2a, 0x54, 0x0a, 0x1a, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x1a, 0x0a, 0x16, 0x41, 0x4c, 0x4c, 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4d, + 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x41, + 0x4e, 0x59, 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x2a, 0x42, 0x0a, 0x12, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x61, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, + 0x11, 0x56, 0x41, 0x52, 0x49, 0x41, 0x4e, 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, + 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x2a, 0x95, 0x02, 0x0a, 0x22, + 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x61, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, - 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x42, 0x4f, - 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, - 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x10, 0x03, 0x12, 0x27, 0x0a, 0x23, 0x44, 0x41, 0x54, 0x45, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x43, - 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, - 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x04, 0x12, 0x28, 0x0a, 0x24, 0x45, - 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, - 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x10, 0x05, 0x32, 0xb1, 0x02, 0x0a, 0x11, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x07, 0x42, - 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x23, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, - 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, - 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x07, 0x56, 0x61, - 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x23, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, - 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x66, 0x6c, 0x69, - 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, - 0x72, 0x69, 0x61, 0x6e, 0x74, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x05, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x12, 0x28, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x66, - 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x92, 0x01, 0x0a, 0x0b, 0x44, 0x61, - 0x74, 0x61, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x1b, 0x45, 0x76, - 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x34, 0x2e, 0x66, 0x6c, 0x69, 0x70, - 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2d, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x42, 0x28, - 0x5a, 0x26, 0x67, 0x6f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x69, 0x6f, 0x2f, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2f, 0x65, 0x76, - 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x54, + 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, + 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, + 0x01, 0x12, 0x25, 0x0a, 0x21, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x53, + 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, + 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x42, 0x4f, 0x4f, 0x4c, + 0x45, 0x41, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x43, + 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x03, + 0x12, 0x27, 0x0a, 0x23, 0x44, 0x41, 0x54, 0x45, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x43, 0x4f, 0x4e, + 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, + 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x04, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x4e, 0x54, + 0x49, 0x54, 0x59, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, + 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x10, 0x05, 0x32, 0xb1, 0x02, 0x0a, 0x11, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x07, 0x42, 0x6f, 0x6f, + 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x23, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x66, 0x6c, 0x69, 0x70, + 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x65, 0x61, 0x6e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x07, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x6e, 0x74, 0x12, 0x23, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, + 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x6e, 0x74, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x12, 0x28, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x66, 0x6c, 0x69, + 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x92, 0x01, 0x0a, 0x0b, 0x44, 0x61, 0x74, 0x61, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x1b, 0x45, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x34, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, + 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, + 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x42, 0x28, 0x5a, 0x26, + 0x67, 0x6f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x69, 0x6f, 0x2f, 0x66, 0x6c, 0x69, 0x70, + 0x74, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2f, 0x65, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2190,7 +2273,7 @@ func file_evaluation_evaluation_proto_rawDescGZIP() []byte { } var file_evaluation_evaluation_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_evaluation_evaluation_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_evaluation_evaluation_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_evaluation_evaluation_proto_goTypes = []any{ (EvaluationReason)(0), // 0: flipt.evaluation.EvaluationReason (ErrorEvaluationReason)(0), // 1: flipt.evaluation.ErrorEvaluationReason @@ -2212,17 +2295,18 @@ var file_evaluation_evaluation_proto_goTypes = []any{ (*EvaluationRolloutThreshold)(nil), // 17: flipt.evaluation.EvaluationRolloutThreshold (*EvaluationRolloutSegment)(nil), // 18: flipt.evaluation.EvaluationRolloutSegment (*EvaluationSegment)(nil), // 19: flipt.evaluation.EvaluationSegment - (*EvaluationFlag)(nil), // 20: flipt.evaluation.EvaluationFlag - (*EvaluationConstraint)(nil), // 21: flipt.evaluation.EvaluationConstraint - (*EvaluationRule)(nil), // 22: flipt.evaluation.EvaluationRule - (*EvaluationNamespace)(nil), // 23: flipt.evaluation.EvaluationNamespace - (*EvaluationNamespaceSnapshot)(nil), // 24: flipt.evaluation.EvaluationNamespaceSnapshot - (*EvaluationNamespaceSnapshotRequest)(nil), // 25: flipt.evaluation.EvaluationNamespaceSnapshotRequest - nil, // 26: flipt.evaluation.EvaluationRequest.ContextEntry - (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp + (*EvaluationVariant)(nil), // 20: flipt.evaluation.EvaluationVariant + (*EvaluationFlag)(nil), // 21: flipt.evaluation.EvaluationFlag + (*EvaluationConstraint)(nil), // 22: flipt.evaluation.EvaluationConstraint + (*EvaluationRule)(nil), // 23: flipt.evaluation.EvaluationRule + (*EvaluationNamespace)(nil), // 24: flipt.evaluation.EvaluationNamespace + (*EvaluationNamespaceSnapshot)(nil), // 25: flipt.evaluation.EvaluationNamespaceSnapshot + (*EvaluationNamespaceSnapshotRequest)(nil), // 26: flipt.evaluation.EvaluationNamespaceSnapshotRequest + nil, // 27: flipt.evaluation.EvaluationRequest.ContextEntry + (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp } var file_evaluation_evaluation_proto_depIdxs = []int32{ - 26, // 0: flipt.evaluation.EvaluationRequest.context:type_name -> flipt.evaluation.EvaluationRequest.ContextEntry + 27, // 0: flipt.evaluation.EvaluationRequest.context:type_name -> flipt.evaluation.EvaluationRequest.ContextEntry 8, // 1: flipt.evaluation.BatchEvaluationRequest.requests:type_name -> flipt.evaluation.EvaluationRequest 11, // 2: flipt.evaluation.BatchEvaluationResponse.responses:type_name -> flipt.evaluation.EvaluationResponse 2, // 3: flipt.evaluation.EvaluationResponse.type:type_name -> flipt.evaluation.EvaluationResponseType @@ -2230,9 +2314,9 @@ var file_evaluation_evaluation_proto_depIdxs = []int32{ 13, // 5: flipt.evaluation.EvaluationResponse.variant_response:type_name -> flipt.evaluation.VariantEvaluationResponse 14, // 6: flipt.evaluation.EvaluationResponse.error_response:type_name -> flipt.evaluation.ErrorEvaluationResponse 0, // 7: flipt.evaluation.BooleanEvaluationResponse.reason:type_name -> flipt.evaluation.EvaluationReason - 27, // 8: flipt.evaluation.BooleanEvaluationResponse.timestamp:type_name -> google.protobuf.Timestamp + 28, // 8: flipt.evaluation.BooleanEvaluationResponse.timestamp:type_name -> google.protobuf.Timestamp 0, // 9: flipt.evaluation.VariantEvaluationResponse.reason:type_name -> flipt.evaluation.EvaluationReason - 27, // 10: flipt.evaluation.VariantEvaluationResponse.timestamp:type_name -> google.protobuf.Timestamp + 28, // 10: flipt.evaluation.VariantEvaluationResponse.timestamp:type_name -> google.protobuf.Timestamp 1, // 11: flipt.evaluation.ErrorEvaluationResponse.reason:type_name -> flipt.evaluation.ErrorEvaluationReason 3, // 12: flipt.evaluation.EvaluationRollout.type:type_name -> flipt.evaluation.EvaluationRolloutType 18, // 13: flipt.evaluation.EvaluationRollout.segment:type_name -> flipt.evaluation.EvaluationRolloutSegment @@ -2240,33 +2324,34 @@ var file_evaluation_evaluation_proto_depIdxs = []int32{ 4, // 15: flipt.evaluation.EvaluationRolloutSegment.segment_operator:type_name -> flipt.evaluation.EvaluationSegmentOperator 19, // 16: flipt.evaluation.EvaluationRolloutSegment.segments:type_name -> flipt.evaluation.EvaluationSegment 5, // 17: flipt.evaluation.EvaluationSegment.match_type:type_name -> flipt.evaluation.EvaluationSegmentMatchType - 27, // 18: flipt.evaluation.EvaluationSegment.created_at:type_name -> google.protobuf.Timestamp - 27, // 19: flipt.evaluation.EvaluationSegment.updated_at:type_name -> google.protobuf.Timestamp - 21, // 20: flipt.evaluation.EvaluationSegment.constraints:type_name -> flipt.evaluation.EvaluationConstraint + 28, // 18: flipt.evaluation.EvaluationSegment.created_at:type_name -> google.protobuf.Timestamp + 28, // 19: flipt.evaluation.EvaluationSegment.updated_at:type_name -> google.protobuf.Timestamp + 22, // 20: flipt.evaluation.EvaluationSegment.constraints:type_name -> flipt.evaluation.EvaluationConstraint 6, // 21: flipt.evaluation.EvaluationFlag.type:type_name -> flipt.evaluation.EvaluationFlagType - 27, // 22: flipt.evaluation.EvaluationFlag.created_at:type_name -> google.protobuf.Timestamp - 27, // 23: flipt.evaluation.EvaluationFlag.updated_at:type_name -> google.protobuf.Timestamp - 22, // 24: flipt.evaluation.EvaluationFlag.rules:type_name -> flipt.evaluation.EvaluationRule + 28, // 22: flipt.evaluation.EvaluationFlag.created_at:type_name -> google.protobuf.Timestamp + 28, // 23: flipt.evaluation.EvaluationFlag.updated_at:type_name -> google.protobuf.Timestamp + 23, // 24: flipt.evaluation.EvaluationFlag.rules:type_name -> flipt.evaluation.EvaluationRule 16, // 25: flipt.evaluation.EvaluationFlag.rollouts:type_name -> flipt.evaluation.EvaluationRollout - 7, // 26: flipt.evaluation.EvaluationConstraint.type:type_name -> flipt.evaluation.EvaluationConstraintComparisonType - 19, // 27: flipt.evaluation.EvaluationRule.segments:type_name -> flipt.evaluation.EvaluationSegment - 4, // 28: flipt.evaluation.EvaluationRule.segment_operator:type_name -> flipt.evaluation.EvaluationSegmentOperator - 15, // 29: flipt.evaluation.EvaluationRule.distributions:type_name -> flipt.evaluation.EvaluationDistribution - 23, // 30: flipt.evaluation.EvaluationNamespaceSnapshot.namespace:type_name -> flipt.evaluation.EvaluationNamespace - 20, // 31: flipt.evaluation.EvaluationNamespaceSnapshot.flags:type_name -> flipt.evaluation.EvaluationFlag - 8, // 32: flipt.evaluation.EvaluationService.Boolean:input_type -> flipt.evaluation.EvaluationRequest - 8, // 33: flipt.evaluation.EvaluationService.Variant:input_type -> flipt.evaluation.EvaluationRequest - 9, // 34: flipt.evaluation.EvaluationService.Batch:input_type -> flipt.evaluation.BatchEvaluationRequest - 25, // 35: flipt.evaluation.DataService.EvaluationSnapshotNamespace:input_type -> flipt.evaluation.EvaluationNamespaceSnapshotRequest - 12, // 36: flipt.evaluation.EvaluationService.Boolean:output_type -> flipt.evaluation.BooleanEvaluationResponse - 13, // 37: flipt.evaluation.EvaluationService.Variant:output_type -> flipt.evaluation.VariantEvaluationResponse - 10, // 38: flipt.evaluation.EvaluationService.Batch:output_type -> flipt.evaluation.BatchEvaluationResponse - 24, // 39: flipt.evaluation.DataService.EvaluationSnapshotNamespace:output_type -> flipt.evaluation.EvaluationNamespaceSnapshot - 36, // [36:40] is the sub-list for method output_type - 32, // [32:36] is the sub-list for method input_type - 32, // [32:32] is the sub-list for extension type_name - 32, // [32:32] is the sub-list for extension extendee - 0, // [0:32] is the sub-list for field type_name + 20, // 26: flipt.evaluation.EvaluationFlag.default_variant:type_name -> flipt.evaluation.EvaluationVariant + 7, // 27: flipt.evaluation.EvaluationConstraint.type:type_name -> flipt.evaluation.EvaluationConstraintComparisonType + 19, // 28: flipt.evaluation.EvaluationRule.segments:type_name -> flipt.evaluation.EvaluationSegment + 4, // 29: flipt.evaluation.EvaluationRule.segment_operator:type_name -> flipt.evaluation.EvaluationSegmentOperator + 15, // 30: flipt.evaluation.EvaluationRule.distributions:type_name -> flipt.evaluation.EvaluationDistribution + 24, // 31: flipt.evaluation.EvaluationNamespaceSnapshot.namespace:type_name -> flipt.evaluation.EvaluationNamespace + 21, // 32: flipt.evaluation.EvaluationNamespaceSnapshot.flags:type_name -> flipt.evaluation.EvaluationFlag + 8, // 33: flipt.evaluation.EvaluationService.Boolean:input_type -> flipt.evaluation.EvaluationRequest + 8, // 34: flipt.evaluation.EvaluationService.Variant:input_type -> flipt.evaluation.EvaluationRequest + 9, // 35: flipt.evaluation.EvaluationService.Batch:input_type -> flipt.evaluation.BatchEvaluationRequest + 26, // 36: flipt.evaluation.DataService.EvaluationSnapshotNamespace:input_type -> flipt.evaluation.EvaluationNamespaceSnapshotRequest + 12, // 37: flipt.evaluation.EvaluationService.Boolean:output_type -> flipt.evaluation.BooleanEvaluationResponse + 13, // 38: flipt.evaluation.EvaluationService.Variant:output_type -> flipt.evaluation.VariantEvaluationResponse + 10, // 39: flipt.evaluation.EvaluationService.Batch:output_type -> flipt.evaluation.BatchEvaluationResponse + 25, // 40: flipt.evaluation.DataService.EvaluationSnapshotNamespace:output_type -> flipt.evaluation.EvaluationNamespaceSnapshot + 37, // [37:41] is the sub-list for method output_type + 33, // [33:37] is the sub-list for method input_type + 33, // [33:33] is the sub-list for extension type_name + 33, // [33:33] is the sub-list for extension extendee + 0, // [0:33] is the sub-list for field type_name } func init() { file_evaluation_evaluation_proto_init() } @@ -2420,7 +2505,7 @@ func file_evaluation_evaluation_proto_init() { } } file_evaluation_evaluation_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*EvaluationFlag); i { + switch v := v.(*EvaluationVariant); i { case 0: return &v.state case 1: @@ -2432,7 +2517,7 @@ func file_evaluation_evaluation_proto_init() { } } file_evaluation_evaluation_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*EvaluationConstraint); i { + switch v := v.(*EvaluationFlag); i { case 0: return &v.state case 1: @@ -2444,7 +2529,7 @@ func file_evaluation_evaluation_proto_init() { } } file_evaluation_evaluation_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*EvaluationRule); i { + switch v := v.(*EvaluationConstraint); i { case 0: return &v.state case 1: @@ -2456,7 +2541,7 @@ func file_evaluation_evaluation_proto_init() { } } file_evaluation_evaluation_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*EvaluationNamespace); i { + switch v := v.(*EvaluationRule); i { case 0: return &v.state case 1: @@ -2468,7 +2553,7 @@ func file_evaluation_evaluation_proto_init() { } } file_evaluation_evaluation_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*EvaluationNamespaceSnapshot); i { + switch v := v.(*EvaluationNamespace); i { case 0: return &v.state case 1: @@ -2480,6 +2565,18 @@ func file_evaluation_evaluation_proto_init() { } } file_evaluation_evaluation_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*EvaluationNamespaceSnapshot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_evaluation_evaluation_proto_msgTypes[18].Exporter = func(v any, i int) any { switch v := v.(*EvaluationNamespaceSnapshotRequest); i { case 0: return &v.state @@ -2501,13 +2598,14 @@ func file_evaluation_evaluation_proto_init() { (*EvaluationRollout_Segment)(nil), (*EvaluationRollout_Threshold)(nil), } + file_evaluation_evaluation_proto_msgTypes[13].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_evaluation_evaluation_proto_rawDesc, NumEnums: 8, - NumMessages: 19, + NumMessages: 20, NumExtensions: 0, NumServices: 2, }, diff --git a/rpc/flipt/evaluation/evaluation.proto b/rpc/flipt/evaluation/evaluation.proto index c06bef3cea..fd29382792 100644 --- a/rpc/flipt/evaluation/evaluation.proto +++ b/rpc/flipt/evaluation/evaluation.proto @@ -142,6 +142,12 @@ message EvaluationSegment { repeated EvaluationConstraint constraints = 7; } +message EvaluationVariant { + string id = 1; + string key = 2; + string attachment = 3; +} + enum EvaluationFlagType { VARIANT_FLAG_TYPE = 0; BOOLEAN_FLAG_TYPE = 1; @@ -157,6 +163,7 @@ message EvaluationFlag { google.protobuf.Timestamp updated_at = 7; repeated EvaluationRule rules = 8; repeated EvaluationRollout rollouts = 9; + optional EvaluationVariant default_variant = 10; } enum EvaluationConstraintComparisonType { diff --git a/rpc/flipt/flipt.pb.go b/rpc/flipt/flipt.pb.go index 308d8f2e3b..9cb22254ca 100644 --- a/rpc/flipt/flipt.pb.go +++ b/rpc/flipt/flipt.pb.go @@ -30,6 +30,7 @@ const ( EvaluationReason_FLAG_NOT_FOUND_EVALUATION_REASON EvaluationReason = 2 EvaluationReason_MATCH_EVALUATION_REASON EvaluationReason = 3 EvaluationReason_ERROR_EVALUATION_REASON EvaluationReason = 4 + EvaluationReason_DEFAULT_EVALUATION_REASON EvaluationReason = 5 ) // Enum value maps for EvaluationReason. @@ -40,6 +41,7 @@ var ( 2: "FLAG_NOT_FOUND_EVALUATION_REASON", 3: "MATCH_EVALUATION_REASON", 4: "ERROR_EVALUATION_REASON", + 5: "DEFAULT_EVALUATION_REASON", } EvaluationReason_value = map[string]int32{ "UNKNOWN_EVALUATION_REASON": 0, @@ -47,6 +49,7 @@ var ( "FLAG_NOT_FOUND_EVALUATION_REASON": 2, "MATCH_EVALUATION_REASON": 3, "ERROR_EVALUATION_REASON": 4, + "DEFAULT_EVALUATION_REASON": 5, } ) @@ -1136,15 +1139,16 @@ type Flag struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - Enabled bool `protobuf:"varint,4,opt,name=enabled,proto3" json:"enabled,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` - Variants []*Variant `protobuf:"bytes,7,rep,name=variants,proto3" json:"variants,omitempty"` - NamespaceKey string `protobuf:"bytes,8,opt,name=namespace_key,json=namespaceKey,proto3" json:"namespace_key,omitempty"` - Type FlagType `protobuf:"varint,9,opt,name=type,proto3,enum=flipt.FlagType" json:"type,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Enabled bool `protobuf:"varint,4,opt,name=enabled,proto3" json:"enabled,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + Variants []*Variant `protobuf:"bytes,7,rep,name=variants,proto3" json:"variants,omitempty"` + NamespaceKey string `protobuf:"bytes,8,opt,name=namespace_key,json=namespaceKey,proto3" json:"namespace_key,omitempty"` + Type FlagType `protobuf:"varint,9,opt,name=type,proto3,enum=flipt.FlagType" json:"type,omitempty"` + DefaultVariant *Variant `protobuf:"bytes,10,opt,name=default_variant,json=defaultVariant,proto3,oneof" json:"default_variant,omitempty"` } func (x *Flag) Reset() { @@ -1242,6 +1246,13 @@ func (x *Flag) GetType() FlagType { return FlagType_VARIANT_FLAG_TYPE } +func (x *Flag) GetDefaultVariant() *Variant { + if x != nil { + return x.DefaultVariant + } + return nil +} + type FlagList struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1541,11 +1552,12 @@ type UpdateFlagRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - Enabled bool `protobuf:"varint,4,opt,name=enabled,proto3" json:"enabled,omitempty"` - NamespaceKey string `protobuf:"bytes,5,opt,name=namespace_key,json=namespaceKey,proto3" json:"namespace_key,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Enabled bool `protobuf:"varint,4,opt,name=enabled,proto3" json:"enabled,omitempty"` + NamespaceKey string `protobuf:"bytes,5,opt,name=namespace_key,json=namespaceKey,proto3" json:"namespace_key,omitempty"` + DefaultVariantId string `protobuf:"bytes,6,opt,name=default_variant_id,json=defaultVariantId,proto3" json:"default_variant_id,omitempty"` } func (x *UpdateFlagRequest) Reset() { @@ -1615,6 +1627,13 @@ func (x *UpdateFlagRequest) GetNamespaceKey() string { return "" } +func (x *UpdateFlagRequest) GetDefaultVariantId() string { + if x != nil { + return x.DefaultVariantId + } + return "" +} + type DeleteFlagRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4882,7 +4901,7 @@ var file_flipt_proto_rawDesc = []byte{ 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2a, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0xd4, 0x02, 0x0a, 0x04, 0x46, 0x6c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0xa6, 0x03, 0x0a, 0x04, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, @@ -4904,44 +4923,37 @@ var file_flipt_proto_rawDesc = []byte{ 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x22, 0x76, 0x0a, 0x08, 0x46, 0x6c, 0x61, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x05, - 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, - 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, - 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, - 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x65, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x46, - 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, - 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, - 0xa5, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1a, 0x0a, 0x06, 0x6f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x6f, - 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xbf, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, - 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x11, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x3c, 0x0a, 0x0f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, + 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x12, + 0x0a, 0x10, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x6e, 0x74, 0x22, 0x76, 0x0a, 0x08, 0x46, 0x6c, 0x61, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x21, + 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, + 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, + 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, + 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x65, 0x0a, 0x0e, 0x47, 0x65, + 0x74, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x23, + 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1a, 0x0a, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xbf, 0x01, 0x0a, 0x11, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, @@ -4950,7 +4962,22 @@ var file_flipt_proto_rawDesc = []byte{ 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x4a, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, + 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xc8, 0x01, 0x0a, 0x11, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x4a, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, @@ -5404,7 +5431,7 @@ var file_flipt_proto_rawDesc = []byte{ 0x72, 0x69, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x2a, 0xb6, + 0x52, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x2a, 0xd5, 0x01, 0x0a, 0x10, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x19, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, @@ -5416,197 +5443,199 @@ var file_flipt_proto_rawDesc = []byte{ 0x17, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, - 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x04, 0x2a, 0x38, 0x0a, 0x08, 0x46, 0x6c, 0x61, 0x67, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x41, 0x52, 0x49, 0x41, 0x4e, 0x54, 0x5f, 0x46, - 0x4c, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x4f, - 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, - 0x01, 0x2a, 0x33, 0x0a, 0x09, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, - 0x0a, 0x0e, 0x41, 0x4c, 0x4c, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x4e, 0x59, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x2a, 0xbf, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x61, - 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, - 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4d, - 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x02, 0x12, 0x1b, - 0x0a, 0x17, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, - 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x44, - 0x41, 0x54, 0x45, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, - 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x04, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e, 0x54, - 0x49, 0x54, 0x59, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, - 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x05, 0x2a, 0x5d, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x6c, - 0x6f, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, - 0x57, 0x4e, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, - 0x00, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x4f, 0x4c, - 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, - 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x02, 0x2a, 0x44, 0x0a, 0x0f, 0x53, 0x65, 0x67, 0x6d, 0x65, - 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x0a, 0x13, 0x4f, 0x52, - 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, - 0x52, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x4e, 0x44, 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, - 0x4e, 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x32, 0xdb, 0x13, - 0x0a, 0x05, 0x46, 0x6c, 0x69, 0x70, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, - 0x61, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x45, 0x76, 0x61, 0x6c, - 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, - 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x53, 0x0a, - 0x0d, 0x42, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x12, 0x1d, - 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, - 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, + 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x46, 0x41, 0x55, + 0x4c, 0x54, 0x5f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, + 0x41, 0x53, 0x4f, 0x4e, 0x10, 0x05, 0x2a, 0x38, 0x0a, 0x08, 0x46, 0x6c, 0x61, 0x67, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x41, 0x52, 0x49, 0x41, 0x4e, 0x54, 0x5f, 0x46, 0x4c, + 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x4f, 0x4f, + 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, + 0x2a, 0x33, 0x0a, 0x09, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, + 0x0e, 0x41, 0x4c, 0x4c, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, + 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x4e, 0x59, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x10, 0x01, 0x2a, 0xbf, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, + 0x69, 0x73, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, + 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, + 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4d, 0x50, + 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x02, 0x12, 0x1b, 0x0a, + 0x17, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, + 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x41, + 0x54, 0x45, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, + 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x04, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e, 0x54, 0x49, + 0x54, 0x59, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x05, 0x2a, 0x5d, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, + 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, + 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, + 0x4f, 0x55, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x48, + 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x10, 0x02, 0x2a, 0x44, 0x0a, 0x0f, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x0a, 0x13, 0x4f, 0x52, 0x5f, + 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, + 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x4e, 0x44, 0x5f, 0x53, 0x45, 0x47, 0x4d, 0x45, 0x4e, + 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x32, 0xdb, 0x13, 0x0a, + 0x05, 0x46, 0x6c, 0x69, 0x70, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x65, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x66, + 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x53, 0x0a, 0x0d, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, - 0x02, 0x01, 0x12, 0x3e, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x1a, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, - 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x14, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0f, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x66, - 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x00, 0x12, - 0x44, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x10, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x66, + 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, + 0x01, 0x12, 0x3e, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x1a, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, + 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, + 0x00, 0x12, 0x45, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x14, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x66, 0x6c, + 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x66, 0x6c, 0x69, + 0x70, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x00, 0x12, 0x44, + 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x1d, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x10, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, + 0x12, 0x2f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x15, 0x2e, 0x66, 0x6c, + 0x69, 0x70, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x22, + 0x00, 0x12, 0x36, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x16, + 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, + 0x6c, 0x61, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x00, + 0x12, 0x35, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x18, + 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, + 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, + 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, + 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0d, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, + 0x70, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x00, 0x12, 0x2f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x15, 0x2e, 0x66, - 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, - 0x22, 0x00, 0x12, 0x36, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, - 0x16, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, + 0x00, 0x12, 0x2f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x15, 0x2e, 0x66, + 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, + 0x22, 0x00, 0x12, 0x36, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x16, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, - 0x46, 0x6c, 0x61, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x22, - 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x12, - 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x6c, - 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, - 0x74, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x22, + 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, + 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, + 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0a, 0x4f, 0x72, 0x64, 0x65, + 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, - 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, - 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0d, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x15, 0x2e, - 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x75, 0x6c, - 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, - 0x12, 0x16, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, - 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, - 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, - 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, - 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x66, 0x6c, 0x69, - 0x70, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0a, 0x4f, 0x72, 0x64, - 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0a, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, - 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, - 0x0a, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x2e, 0x66, 0x6c, - 0x69, 0x70, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x65, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0a, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0a, + 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, + 0x70, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x6f, 0x6c, + 0x6c, 0x6f, 0x75, 0x74, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, + 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x12, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, + 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x6f, - 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, - 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, - 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, - 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, - 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, - 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, - 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, - 0x12, 0x46, 0x0a, 0x0d, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, - 0x73, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, - 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, - 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x13, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x52, 0x6f, + 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, + 0x46, 0x0a, 0x0d, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, + 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x6f, + 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, - 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x74, + 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x66, - 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x73, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, - 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x47, - 0x65, 0x74, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, + 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, + 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x66, 0x6c, + 0x69, 0x70, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, + 0x00, 0x12, 0x3f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x19, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x66, + 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, + 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, - 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x19, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, - 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, - 0x74, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, - 0x74, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, - 0x74, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x67, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x10, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, - 0x1e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x11, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, - 0x6e, 0x74, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, - 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x4c, 0x0a, - 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, - 0x74, 0x12, 0x1e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x1d, 0x5a, 0x1b, 0x67, - 0x6f, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x69, 0x6f, 0x2f, 0x66, 0x6c, 0x69, 0x70, 0x74, - 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x0e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x10, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x1e, + 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, + 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, + 0x74, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, + 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x10, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, + 0x12, 0x1e, 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x1d, 0x5a, 0x1b, 0x67, 0x6f, + 0x2e, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2e, 0x69, 0x6f, 0x2f, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x2f, + 0x72, 0x70, 0x63, 0x2f, 0x66, 0x6c, 0x69, 0x70, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -5704,123 +5733,124 @@ var file_flipt_proto_depIdxs = []int32{ 63, // 10: flipt.Flag.updated_at:type_name -> google.protobuf.Timestamp 24, // 11: flipt.Flag.variants:type_name -> flipt.Variant 1, // 12: flipt.Flag.type:type_name -> flipt.FlagType - 17, // 13: flipt.FlagList.flags:type_name -> flipt.Flag - 1, // 14: flipt.CreateFlagRequest.type:type_name -> flipt.FlagType - 63, // 15: flipt.Variant.created_at:type_name -> google.protobuf.Timestamp - 63, // 16: flipt.Variant.updated_at:type_name -> google.protobuf.Timestamp - 63, // 17: flipt.Segment.created_at:type_name -> google.protobuf.Timestamp - 63, // 18: flipt.Segment.updated_at:type_name -> google.protobuf.Timestamp - 35, // 19: flipt.Segment.constraints:type_name -> flipt.Constraint - 2, // 20: flipt.Segment.match_type:type_name -> flipt.MatchType - 28, // 21: flipt.SegmentList.segments:type_name -> flipt.Segment - 2, // 22: flipt.CreateSegmentRequest.match_type:type_name -> flipt.MatchType - 2, // 23: flipt.UpdateSegmentRequest.match_type:type_name -> flipt.MatchType - 3, // 24: flipt.Constraint.type:type_name -> flipt.ComparisonType - 63, // 25: flipt.Constraint.created_at:type_name -> google.protobuf.Timestamp - 63, // 26: flipt.Constraint.updated_at:type_name -> google.protobuf.Timestamp - 3, // 27: flipt.CreateConstraintRequest.type:type_name -> flipt.ComparisonType - 3, // 28: flipt.UpdateConstraintRequest.type:type_name -> flipt.ComparisonType - 4, // 29: flipt.Rollout.type:type_name -> flipt.RolloutType - 63, // 30: flipt.Rollout.created_at:type_name -> google.protobuf.Timestamp - 63, // 31: flipt.Rollout.updated_at:type_name -> google.protobuf.Timestamp - 40, // 32: flipt.Rollout.segment:type_name -> flipt.RolloutSegment - 41, // 33: flipt.Rollout.threshold:type_name -> flipt.RolloutThreshold - 5, // 34: flipt.RolloutSegment.segment_operator:type_name -> flipt.SegmentOperator - 39, // 35: flipt.RolloutList.rules:type_name -> flipt.Rollout - 40, // 36: flipt.CreateRolloutRequest.segment:type_name -> flipt.RolloutSegment - 41, // 37: flipt.CreateRolloutRequest.threshold:type_name -> flipt.RolloutThreshold - 40, // 38: flipt.UpdateRolloutRequest.segment:type_name -> flipt.RolloutSegment - 41, // 39: flipt.UpdateRolloutRequest.threshold:type_name -> flipt.RolloutThreshold - 57, // 40: flipt.Rule.distributions:type_name -> flipt.Distribution - 63, // 41: flipt.Rule.created_at:type_name -> google.protobuf.Timestamp - 63, // 42: flipt.Rule.updated_at:type_name -> google.protobuf.Timestamp - 5, // 43: flipt.Rule.segment_operator:type_name -> flipt.SegmentOperator - 49, // 44: flipt.RuleList.rules:type_name -> flipt.Rule - 5, // 45: flipt.CreateRuleRequest.segment_operator:type_name -> flipt.SegmentOperator - 5, // 46: flipt.UpdateRuleRequest.segment_operator:type_name -> flipt.SegmentOperator - 63, // 47: flipt.Distribution.created_at:type_name -> google.protobuf.Timestamp - 63, // 48: flipt.Distribution.updated_at:type_name -> google.protobuf.Timestamp - 6, // 49: flipt.Flipt.Evaluate:input_type -> flipt.EvaluationRequest - 7, // 50: flipt.Flipt.BatchEvaluate:input_type -> flipt.BatchEvaluationRequest - 12, // 51: flipt.Flipt.GetNamespace:input_type -> flipt.GetNamespaceRequest - 13, // 52: flipt.Flipt.ListNamespaces:input_type -> flipt.ListNamespaceRequest - 14, // 53: flipt.Flipt.CreateNamespace:input_type -> flipt.CreateNamespaceRequest - 15, // 54: flipt.Flipt.UpdateNamespace:input_type -> flipt.UpdateNamespaceRequest - 16, // 55: flipt.Flipt.DeleteNamespace:input_type -> flipt.DeleteNamespaceRequest - 19, // 56: flipt.Flipt.GetFlag:input_type -> flipt.GetFlagRequest - 20, // 57: flipt.Flipt.ListFlags:input_type -> flipt.ListFlagRequest - 21, // 58: flipt.Flipt.CreateFlag:input_type -> flipt.CreateFlagRequest - 22, // 59: flipt.Flipt.UpdateFlag:input_type -> flipt.UpdateFlagRequest - 23, // 60: flipt.Flipt.DeleteFlag:input_type -> flipt.DeleteFlagRequest - 25, // 61: flipt.Flipt.CreateVariant:input_type -> flipt.CreateVariantRequest - 26, // 62: flipt.Flipt.UpdateVariant:input_type -> flipt.UpdateVariantRequest - 27, // 63: flipt.Flipt.DeleteVariant:input_type -> flipt.DeleteVariantRequest - 52, // 64: flipt.Flipt.GetRule:input_type -> flipt.GetRuleRequest - 51, // 65: flipt.Flipt.ListRules:input_type -> flipt.ListRuleRequest - 53, // 66: flipt.Flipt.CreateRule:input_type -> flipt.CreateRuleRequest - 54, // 67: flipt.Flipt.UpdateRule:input_type -> flipt.UpdateRuleRequest - 56, // 68: flipt.Flipt.OrderRules:input_type -> flipt.OrderRulesRequest - 55, // 69: flipt.Flipt.DeleteRule:input_type -> flipt.DeleteRuleRequest - 44, // 70: flipt.Flipt.GetRollout:input_type -> flipt.GetRolloutRequest - 43, // 71: flipt.Flipt.ListRollouts:input_type -> flipt.ListRolloutRequest - 45, // 72: flipt.Flipt.CreateRollout:input_type -> flipt.CreateRolloutRequest - 46, // 73: flipt.Flipt.UpdateRollout:input_type -> flipt.UpdateRolloutRequest - 47, // 74: flipt.Flipt.DeleteRollout:input_type -> flipt.DeleteRolloutRequest - 48, // 75: flipt.Flipt.OrderRollouts:input_type -> flipt.OrderRolloutsRequest - 58, // 76: flipt.Flipt.CreateDistribution:input_type -> flipt.CreateDistributionRequest - 59, // 77: flipt.Flipt.UpdateDistribution:input_type -> flipt.UpdateDistributionRequest - 60, // 78: flipt.Flipt.DeleteDistribution:input_type -> flipt.DeleteDistributionRequest - 30, // 79: flipt.Flipt.GetSegment:input_type -> flipt.GetSegmentRequest - 31, // 80: flipt.Flipt.ListSegments:input_type -> flipt.ListSegmentRequest - 32, // 81: flipt.Flipt.CreateSegment:input_type -> flipt.CreateSegmentRequest - 33, // 82: flipt.Flipt.UpdateSegment:input_type -> flipt.UpdateSegmentRequest - 34, // 83: flipt.Flipt.DeleteSegment:input_type -> flipt.DeleteSegmentRequest - 36, // 84: flipt.Flipt.CreateConstraint:input_type -> flipt.CreateConstraintRequest - 37, // 85: flipt.Flipt.UpdateConstraint:input_type -> flipt.UpdateConstraintRequest - 38, // 86: flipt.Flipt.DeleteConstraint:input_type -> flipt.DeleteConstraintRequest - 9, // 87: flipt.Flipt.Evaluate:output_type -> flipt.EvaluationResponse - 8, // 88: flipt.Flipt.BatchEvaluate:output_type -> flipt.BatchEvaluationResponse - 10, // 89: flipt.Flipt.GetNamespace:output_type -> flipt.Namespace - 11, // 90: flipt.Flipt.ListNamespaces:output_type -> flipt.NamespaceList - 10, // 91: flipt.Flipt.CreateNamespace:output_type -> flipt.Namespace - 10, // 92: flipt.Flipt.UpdateNamespace:output_type -> flipt.Namespace - 64, // 93: flipt.Flipt.DeleteNamespace:output_type -> google.protobuf.Empty - 17, // 94: flipt.Flipt.GetFlag:output_type -> flipt.Flag - 18, // 95: flipt.Flipt.ListFlags:output_type -> flipt.FlagList - 17, // 96: flipt.Flipt.CreateFlag:output_type -> flipt.Flag - 17, // 97: flipt.Flipt.UpdateFlag:output_type -> flipt.Flag - 64, // 98: flipt.Flipt.DeleteFlag:output_type -> google.protobuf.Empty - 24, // 99: flipt.Flipt.CreateVariant:output_type -> flipt.Variant - 24, // 100: flipt.Flipt.UpdateVariant:output_type -> flipt.Variant - 64, // 101: flipt.Flipt.DeleteVariant:output_type -> google.protobuf.Empty - 49, // 102: flipt.Flipt.GetRule:output_type -> flipt.Rule - 50, // 103: flipt.Flipt.ListRules:output_type -> flipt.RuleList - 49, // 104: flipt.Flipt.CreateRule:output_type -> flipt.Rule - 49, // 105: flipt.Flipt.UpdateRule:output_type -> flipt.Rule - 64, // 106: flipt.Flipt.OrderRules:output_type -> google.protobuf.Empty - 64, // 107: flipt.Flipt.DeleteRule:output_type -> google.protobuf.Empty - 39, // 108: flipt.Flipt.GetRollout:output_type -> flipt.Rollout - 42, // 109: flipt.Flipt.ListRollouts:output_type -> flipt.RolloutList - 39, // 110: flipt.Flipt.CreateRollout:output_type -> flipt.Rollout - 39, // 111: flipt.Flipt.UpdateRollout:output_type -> flipt.Rollout - 64, // 112: flipt.Flipt.DeleteRollout:output_type -> google.protobuf.Empty - 64, // 113: flipt.Flipt.OrderRollouts:output_type -> google.protobuf.Empty - 57, // 114: flipt.Flipt.CreateDistribution:output_type -> flipt.Distribution - 57, // 115: flipt.Flipt.UpdateDistribution:output_type -> flipt.Distribution - 64, // 116: flipt.Flipt.DeleteDistribution:output_type -> google.protobuf.Empty - 28, // 117: flipt.Flipt.GetSegment:output_type -> flipt.Segment - 29, // 118: flipt.Flipt.ListSegments:output_type -> flipt.SegmentList - 28, // 119: flipt.Flipt.CreateSegment:output_type -> flipt.Segment - 28, // 120: flipt.Flipt.UpdateSegment:output_type -> flipt.Segment - 64, // 121: flipt.Flipt.DeleteSegment:output_type -> google.protobuf.Empty - 35, // 122: flipt.Flipt.CreateConstraint:output_type -> flipt.Constraint - 35, // 123: flipt.Flipt.UpdateConstraint:output_type -> flipt.Constraint - 64, // 124: flipt.Flipt.DeleteConstraint:output_type -> google.protobuf.Empty - 87, // [87:125] is the sub-list for method output_type - 49, // [49:87] is the sub-list for method input_type - 49, // [49:49] is the sub-list for extension type_name - 49, // [49:49] is the sub-list for extension extendee - 0, // [0:49] is the sub-list for field type_name + 24, // 13: flipt.Flag.default_variant:type_name -> flipt.Variant + 17, // 14: flipt.FlagList.flags:type_name -> flipt.Flag + 1, // 15: flipt.CreateFlagRequest.type:type_name -> flipt.FlagType + 63, // 16: flipt.Variant.created_at:type_name -> google.protobuf.Timestamp + 63, // 17: flipt.Variant.updated_at:type_name -> google.protobuf.Timestamp + 63, // 18: flipt.Segment.created_at:type_name -> google.protobuf.Timestamp + 63, // 19: flipt.Segment.updated_at:type_name -> google.protobuf.Timestamp + 35, // 20: flipt.Segment.constraints:type_name -> flipt.Constraint + 2, // 21: flipt.Segment.match_type:type_name -> flipt.MatchType + 28, // 22: flipt.SegmentList.segments:type_name -> flipt.Segment + 2, // 23: flipt.CreateSegmentRequest.match_type:type_name -> flipt.MatchType + 2, // 24: flipt.UpdateSegmentRequest.match_type:type_name -> flipt.MatchType + 3, // 25: flipt.Constraint.type:type_name -> flipt.ComparisonType + 63, // 26: flipt.Constraint.created_at:type_name -> google.protobuf.Timestamp + 63, // 27: flipt.Constraint.updated_at:type_name -> google.protobuf.Timestamp + 3, // 28: flipt.CreateConstraintRequest.type:type_name -> flipt.ComparisonType + 3, // 29: flipt.UpdateConstraintRequest.type:type_name -> flipt.ComparisonType + 4, // 30: flipt.Rollout.type:type_name -> flipt.RolloutType + 63, // 31: flipt.Rollout.created_at:type_name -> google.protobuf.Timestamp + 63, // 32: flipt.Rollout.updated_at:type_name -> google.protobuf.Timestamp + 40, // 33: flipt.Rollout.segment:type_name -> flipt.RolloutSegment + 41, // 34: flipt.Rollout.threshold:type_name -> flipt.RolloutThreshold + 5, // 35: flipt.RolloutSegment.segment_operator:type_name -> flipt.SegmentOperator + 39, // 36: flipt.RolloutList.rules:type_name -> flipt.Rollout + 40, // 37: flipt.CreateRolloutRequest.segment:type_name -> flipt.RolloutSegment + 41, // 38: flipt.CreateRolloutRequest.threshold:type_name -> flipt.RolloutThreshold + 40, // 39: flipt.UpdateRolloutRequest.segment:type_name -> flipt.RolloutSegment + 41, // 40: flipt.UpdateRolloutRequest.threshold:type_name -> flipt.RolloutThreshold + 57, // 41: flipt.Rule.distributions:type_name -> flipt.Distribution + 63, // 42: flipt.Rule.created_at:type_name -> google.protobuf.Timestamp + 63, // 43: flipt.Rule.updated_at:type_name -> google.protobuf.Timestamp + 5, // 44: flipt.Rule.segment_operator:type_name -> flipt.SegmentOperator + 49, // 45: flipt.RuleList.rules:type_name -> flipt.Rule + 5, // 46: flipt.CreateRuleRequest.segment_operator:type_name -> flipt.SegmentOperator + 5, // 47: flipt.UpdateRuleRequest.segment_operator:type_name -> flipt.SegmentOperator + 63, // 48: flipt.Distribution.created_at:type_name -> google.protobuf.Timestamp + 63, // 49: flipt.Distribution.updated_at:type_name -> google.protobuf.Timestamp + 6, // 50: flipt.Flipt.Evaluate:input_type -> flipt.EvaluationRequest + 7, // 51: flipt.Flipt.BatchEvaluate:input_type -> flipt.BatchEvaluationRequest + 12, // 52: flipt.Flipt.GetNamespace:input_type -> flipt.GetNamespaceRequest + 13, // 53: flipt.Flipt.ListNamespaces:input_type -> flipt.ListNamespaceRequest + 14, // 54: flipt.Flipt.CreateNamespace:input_type -> flipt.CreateNamespaceRequest + 15, // 55: flipt.Flipt.UpdateNamespace:input_type -> flipt.UpdateNamespaceRequest + 16, // 56: flipt.Flipt.DeleteNamespace:input_type -> flipt.DeleteNamespaceRequest + 19, // 57: flipt.Flipt.GetFlag:input_type -> flipt.GetFlagRequest + 20, // 58: flipt.Flipt.ListFlags:input_type -> flipt.ListFlagRequest + 21, // 59: flipt.Flipt.CreateFlag:input_type -> flipt.CreateFlagRequest + 22, // 60: flipt.Flipt.UpdateFlag:input_type -> flipt.UpdateFlagRequest + 23, // 61: flipt.Flipt.DeleteFlag:input_type -> flipt.DeleteFlagRequest + 25, // 62: flipt.Flipt.CreateVariant:input_type -> flipt.CreateVariantRequest + 26, // 63: flipt.Flipt.UpdateVariant:input_type -> flipt.UpdateVariantRequest + 27, // 64: flipt.Flipt.DeleteVariant:input_type -> flipt.DeleteVariantRequest + 52, // 65: flipt.Flipt.GetRule:input_type -> flipt.GetRuleRequest + 51, // 66: flipt.Flipt.ListRules:input_type -> flipt.ListRuleRequest + 53, // 67: flipt.Flipt.CreateRule:input_type -> flipt.CreateRuleRequest + 54, // 68: flipt.Flipt.UpdateRule:input_type -> flipt.UpdateRuleRequest + 56, // 69: flipt.Flipt.OrderRules:input_type -> flipt.OrderRulesRequest + 55, // 70: flipt.Flipt.DeleteRule:input_type -> flipt.DeleteRuleRequest + 44, // 71: flipt.Flipt.GetRollout:input_type -> flipt.GetRolloutRequest + 43, // 72: flipt.Flipt.ListRollouts:input_type -> flipt.ListRolloutRequest + 45, // 73: flipt.Flipt.CreateRollout:input_type -> flipt.CreateRolloutRequest + 46, // 74: flipt.Flipt.UpdateRollout:input_type -> flipt.UpdateRolloutRequest + 47, // 75: flipt.Flipt.DeleteRollout:input_type -> flipt.DeleteRolloutRequest + 48, // 76: flipt.Flipt.OrderRollouts:input_type -> flipt.OrderRolloutsRequest + 58, // 77: flipt.Flipt.CreateDistribution:input_type -> flipt.CreateDistributionRequest + 59, // 78: flipt.Flipt.UpdateDistribution:input_type -> flipt.UpdateDistributionRequest + 60, // 79: flipt.Flipt.DeleteDistribution:input_type -> flipt.DeleteDistributionRequest + 30, // 80: flipt.Flipt.GetSegment:input_type -> flipt.GetSegmentRequest + 31, // 81: flipt.Flipt.ListSegments:input_type -> flipt.ListSegmentRequest + 32, // 82: flipt.Flipt.CreateSegment:input_type -> flipt.CreateSegmentRequest + 33, // 83: flipt.Flipt.UpdateSegment:input_type -> flipt.UpdateSegmentRequest + 34, // 84: flipt.Flipt.DeleteSegment:input_type -> flipt.DeleteSegmentRequest + 36, // 85: flipt.Flipt.CreateConstraint:input_type -> flipt.CreateConstraintRequest + 37, // 86: flipt.Flipt.UpdateConstraint:input_type -> flipt.UpdateConstraintRequest + 38, // 87: flipt.Flipt.DeleteConstraint:input_type -> flipt.DeleteConstraintRequest + 9, // 88: flipt.Flipt.Evaluate:output_type -> flipt.EvaluationResponse + 8, // 89: flipt.Flipt.BatchEvaluate:output_type -> flipt.BatchEvaluationResponse + 10, // 90: flipt.Flipt.GetNamespace:output_type -> flipt.Namespace + 11, // 91: flipt.Flipt.ListNamespaces:output_type -> flipt.NamespaceList + 10, // 92: flipt.Flipt.CreateNamespace:output_type -> flipt.Namespace + 10, // 93: flipt.Flipt.UpdateNamespace:output_type -> flipt.Namespace + 64, // 94: flipt.Flipt.DeleteNamespace:output_type -> google.protobuf.Empty + 17, // 95: flipt.Flipt.GetFlag:output_type -> flipt.Flag + 18, // 96: flipt.Flipt.ListFlags:output_type -> flipt.FlagList + 17, // 97: flipt.Flipt.CreateFlag:output_type -> flipt.Flag + 17, // 98: flipt.Flipt.UpdateFlag:output_type -> flipt.Flag + 64, // 99: flipt.Flipt.DeleteFlag:output_type -> google.protobuf.Empty + 24, // 100: flipt.Flipt.CreateVariant:output_type -> flipt.Variant + 24, // 101: flipt.Flipt.UpdateVariant:output_type -> flipt.Variant + 64, // 102: flipt.Flipt.DeleteVariant:output_type -> google.protobuf.Empty + 49, // 103: flipt.Flipt.GetRule:output_type -> flipt.Rule + 50, // 104: flipt.Flipt.ListRules:output_type -> flipt.RuleList + 49, // 105: flipt.Flipt.CreateRule:output_type -> flipt.Rule + 49, // 106: flipt.Flipt.UpdateRule:output_type -> flipt.Rule + 64, // 107: flipt.Flipt.OrderRules:output_type -> google.protobuf.Empty + 64, // 108: flipt.Flipt.DeleteRule:output_type -> google.protobuf.Empty + 39, // 109: flipt.Flipt.GetRollout:output_type -> flipt.Rollout + 42, // 110: flipt.Flipt.ListRollouts:output_type -> flipt.RolloutList + 39, // 111: flipt.Flipt.CreateRollout:output_type -> flipt.Rollout + 39, // 112: flipt.Flipt.UpdateRollout:output_type -> flipt.Rollout + 64, // 113: flipt.Flipt.DeleteRollout:output_type -> google.protobuf.Empty + 64, // 114: flipt.Flipt.OrderRollouts:output_type -> google.protobuf.Empty + 57, // 115: flipt.Flipt.CreateDistribution:output_type -> flipt.Distribution + 57, // 116: flipt.Flipt.UpdateDistribution:output_type -> flipt.Distribution + 64, // 117: flipt.Flipt.DeleteDistribution:output_type -> google.protobuf.Empty + 28, // 118: flipt.Flipt.GetSegment:output_type -> flipt.Segment + 29, // 119: flipt.Flipt.ListSegments:output_type -> flipt.SegmentList + 28, // 120: flipt.Flipt.CreateSegment:output_type -> flipt.Segment + 28, // 121: flipt.Flipt.UpdateSegment:output_type -> flipt.Segment + 64, // 122: flipt.Flipt.DeleteSegment:output_type -> google.protobuf.Empty + 35, // 123: flipt.Flipt.CreateConstraint:output_type -> flipt.Constraint + 35, // 124: flipt.Flipt.UpdateConstraint:output_type -> flipt.Constraint + 64, // 125: flipt.Flipt.DeleteConstraint:output_type -> google.protobuf.Empty + 88, // [88:126] is the sub-list for method output_type + 50, // [50:88] is the sub-list for method input_type + 50, // [50:50] is the sub-list for extension type_name + 50, // [50:50] is the sub-list for extension extendee + 0, // [0:50] is the sub-list for field type_name } func init() { file_flipt_proto_init() } @@ -6490,6 +6520,7 @@ func file_flipt_proto_init() { } } } + file_flipt_proto_msgTypes[11].OneofWrappers = []any{} file_flipt_proto_msgTypes[33].OneofWrappers = []any{ (*Rollout_Segment)(nil), (*Rollout_Threshold)(nil), diff --git a/rpc/flipt/flipt.proto b/rpc/flipt/flipt.proto index fdcecfb021..1cf800eb96 100644 --- a/rpc/flipt/flipt.proto +++ b/rpc/flipt/flipt.proto @@ -50,6 +50,7 @@ enum EvaluationReason { FLAG_NOT_FOUND_EVALUATION_REASON = 2; MATCH_EVALUATION_REASON = 3; ERROR_EVALUATION_REASON = 4; + DEFAULT_EVALUATION_REASON = 5; } message Namespace { @@ -110,6 +111,7 @@ message Flag { repeated Variant variants = 7; string namespace_key = 8; FlagType type = 9; + optional Variant default_variant = 10; } message FlagList { @@ -147,6 +149,7 @@ message UpdateFlagRequest { string description = 3; bool enabled = 4; string namespace_key = 5; + string default_variant_id = 6; } message DeleteFlagRequest { diff --git a/ui/package-lock.json b/ui/package-lock.json index 62c934f36c..2f9d638f70 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -47,7 +47,7 @@ }, "devDependencies": { "@babel/preset-typescript": "^7.24.7", - "@playwright/test": "^1.44.1", + "@playwright/test": "^1.45.2", "@tailwindcss/forms": "^0.5.7", "@types/jest": "^29.5.12", "@types/loadable__component": "^5.13.9", @@ -3736,46 +3736,16 @@ } }, "node_modules/@playwright/test": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.1.tgz", - "integrity": "sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==", - "dev": true, - "dependencies": { - "playwright": "1.45.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@playwright/test/node_modules/playwright": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz", - "integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==", + "version": "1.45.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz", + "integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==", "dev": true, "dependencies": { - "playwright-core": "1.45.1" + "playwright": "1.45.2" }, "bin": { "playwright": "cli.js" }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/@playwright/test/node_modules/playwright-core": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz", - "integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==", - "dev": true, - "bin": { - "playwright-core": "cli.js" - }, "engines": { "node": ">=18" } @@ -17048,30 +17018,12 @@ "dev": true }, "@playwright/test": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.1.tgz", - "integrity": "sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==", + "version": "1.45.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz", + "integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==", "dev": true, "requires": { - "playwright": "1.45.1" - }, - "dependencies": { - "playwright": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz", - "integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==", - "dev": true, - "requires": { - "fsevents": "2.3.2", - "playwright-core": "1.45.1" - } - }, - "playwright-core": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz", - "integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==", - "dev": true - } + "playwright": "1.45.2" } }, "@radix-ui/primitive": { diff --git a/ui/package.json b/ui/package.json index 87ddccc2d3..fce624ce17 100644 --- a/ui/package.json +++ b/ui/package.json @@ -53,7 +53,7 @@ }, "devDependencies": { "@babel/preset-typescript": "^7.24.7", - "@playwright/test": "^1.44.1", + "@playwright/test": "^1.45.2", "@tailwindcss/forms": "^0.5.7", "@types/jest": "^29.5.12", "@types/loadable__component": "^5.13.9", diff --git a/ui/src/app/flags/flagsApi.ts b/ui/src/app/flags/flagsApi.ts index e82d9cc023..2aceddd3bf 100644 --- a/ui/src/app/flags/flagsApi.ts +++ b/ui/src/app/flags/flagsApi.ts @@ -68,10 +68,16 @@ export const flagsApi = createApi({ { namespaceKey: string; flagKey: string; values: IFlagBase } >({ query({ namespaceKey, flagKey, values }) { + // create new object 'values' to remap defaultVariant to defaultVariantId + const update = { + defaultVariantId: values.defaultVariant?.id || null, + ...values + }; + delete update.defaultVariant; return { url: `/namespaces/${namespaceKey}/flags/${flagKey}`, method: 'PUT', - body: values + body: update }; }, invalidatesTags: (_result, _error, { namespaceKey, flagKey }) => [ diff --git a/ui/src/app/flags/rollouts/Rollouts.tsx b/ui/src/app/flags/rollouts/Rollouts.tsx index 11479e240b..49bf5d2e8f 100644 --- a/ui/src/app/flags/rollouts/Rollouts.tsx +++ b/ui/src/app/flags/rollouts/Rollouts.tsx @@ -42,6 +42,44 @@ type RolloutsProps = { flag: IFlag; }; +export function DefaultRollout(props: RolloutsProps) { + const { flag } = props; + + return ( +
+
+
+
+ +

+ Default Rollout +

+ +
+
+
+
+
+

+ This is the default value that will be returned if no other + rules match. It is directly tied to the flag enabled state. +

+
+
+ + Value + + + {flag.enabled ? 'True' : 'False'} + +
+
+
+
+
+ ); +} + export default function Rollouts(props: RolloutsProps) { const { flag } = props; @@ -266,7 +304,7 @@ export default function Rollouts(props: RolloutsProps) {

- Rules are evaluated in order from{' '} + Rollout rules are evaluated in order from{' '} top to bottom. The first rule that matches will be applied.

@@ -319,38 +357,7 @@ export default function Rollouts(props: RolloutsProps) { )} -
-
-
-
- -

- Default Rollout -

- -
-
-
-
-
-

- This is the default value that will be returned if no - other rules match. It is directly tied to the flag - enabled state. -

-
-
- - Value - - - {flag.enabled ? 'True' : 'False'} - -
-
-
-
-
+
diff --git a/ui/src/app/flags/rules/Rules.tsx b/ui/src/app/flags/rules/Rules.tsx index 45422a8fef..0d11abc7b3 100644 --- a/ui/src/app/flags/rules/Rules.tsx +++ b/ui/src/app/flags/rules/Rules.tsx @@ -13,7 +13,8 @@ import { sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable'; -import { PlusIcon } from '@heroicons/react/24/outline'; +import { PlusIcon, StarIcon } from '@heroicons/react/24/outline'; +import { Form, Formik } from 'formik'; import { useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { useOutletContext } from 'react-router-dom'; @@ -27,6 +28,7 @@ import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice'; import { useListSegmentsQuery } from '~/app/segments/segmentsApi'; import EmptyState from '~/components/EmptyState'; import Button from '~/components/forms/buttons/Button'; + import Loading from '~/components/Loading'; import Modal from '~/components/Modal'; import DeletePanel from '~/components/panels/DeletePanel'; @@ -41,12 +43,165 @@ import { IEvaluatable } from '~/types/Evaluatable'; import { IFlag } from '~/types/Flag'; import { IRule } from '~/types/Rule'; import { ISegment, SegmentOperatorType } from '~/types/Segment'; -import { IVariant } from '~/types/Variant'; +import { + FilterableVariant, + IVariant, + toFilterableVariant +} from '~/types/Variant'; +import { useUpdateFlagMutation } from '~/app/flags/flagsApi'; +import { INamespace } from '~/types/Namespace'; +import TextButton from '~/components/forms/buttons/TextButton'; +import SingleDistributionFormInput from '~/components/rules/forms/SingleDistributionForm'; type RulesProps = { flag: IFlag; }; +export function DefaultVariant(props: RulesProps) { + const { flag } = props; + + const { setError, clearError } = useError(); + const { setSuccess } = useSuccess(); + + const namespace = useSelector(selectCurrentNamespace) as INamespace; + + const [selectedVariant, setSelectedVariant] = + useState(() => { + return toFilterableVariant(flag.defaultVariant); + }); + + const [updateFlag] = useUpdateFlagMutation(); + + const handleRemove = async () => { + try { + setSelectedVariant(null); + await updateFlag({ + namespaceKey: namespace.key, + flagKey: flag.key, + values: { + ...flag, + defaultVariant: undefined + } + }); + clearError(); + setSuccess('Successfully removed default variant'); + } catch (err) { + setError(err); + } + }; + + const handleSubmit = async () => { + await updateFlag({ + namespaceKey: namespace.key, + flagKey: flag.key, + values: { + ...flag, + defaultVariant: { + id: selectedVariant?.id ?? '' + } as IVariant + } + }); + }; + + return ( + { + handleSubmit() + .then(() => { + clearError(); + setSuccess('Successfully updated default variant'); + }) + .catch((err) => { + setError(err); + }) + .finally(() => { + setSubmitting(false); + }); + }} + > + {(formik) => { + return ( +
+
+
+ +

+ Default Rule +

+ +
+
+ +
+

+ This is the default value that will be returned if no other + rules match. +

+
+
+
+
+
+
+ {flag.variants && flag.variants.length > 0 && ( + + )} +
+
+
+
+ handleRemove()} + > + Remove + + { + formik.resetForm(); + setSelectedVariant( + toFilterableVariant(flag.defaultVariant) + ); + }} + > + Reset + + + {formik.isSubmitting ? : 'Update'} + +
+
+
+
+
+
+ ); + }} +
+ ); +} + export default function Rules() { const { flag } = useOutletContext(); @@ -69,6 +224,8 @@ export default function Rules() { [segmentsList] ); + const showDefaultVariant = flag.variants && flag.variants.length > 0; + const [deleteRule] = useDeleteRuleMutation(); const [orderRules] = useOrderRulesMutation(); @@ -248,7 +405,7 @@ export default function Rules() { Enable rich targeting and segmentation for evaluating your flags

- {rules && rules.length > 0 && ( + {((rules && rules.length > 0) || showDefaultVariant) && (