feat: add targeting validation (#1146)

- adds targeting validation
- updates sample json files
- updates schemas modules to most recent release

Closes #1140 

Signed-off-by: Best Olunusi <olunusibest@gmail.com>
Co-authored-by: Todd Baert <todd.baert@dynatrace.com>
This commit is contained in:
Best Olunusi 2024-01-16 12:28:20 -06:00 committed by GitHub
parent 2adfa573a2
commit b727dd00c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 178 additions and 62 deletions

View File

@ -12,7 +12,7 @@ require (
github.com/fsnotify/fsnotify v1.7.0
github.com/golang/mock v1.6.0
github.com/open-feature/open-feature-operator/apis v0.2.38-0.20231117101310-726a7f714906
github.com/open-feature/schemas v0.2.8
github.com/open-feature/schemas v0.2.9-0.20240115143711-4a0be4f48816
github.com/prometheus/client_golang v1.18.0
github.com/robfig/cron v1.2.0
github.com/rs/cors v1.10.1

View File

@ -640,6 +640,8 @@ github.com/open-feature/open-feature-operator/apis v0.2.38-0.20231117101310-726a
github.com/open-feature/open-feature-operator/apis v0.2.38-0.20231117101310-726a7f714906/go.mod h1:YtdYEXJHo9iKwmchxbwGGsmu33FbugMQ8lKGarA9UYM=
github.com/open-feature/schemas v0.2.8 h1:oA75hJXpOd9SFgmNI2IAxWZkwzQPUDm7Jyyh3q489wM=
github.com/open-feature/schemas v0.2.8/go.mod h1:vj+rfTsOLlh5PtGGkAbitnJmFPYuTHXTjOy13kzNgKQ=
github.com/open-feature/schemas v0.2.9-0.20240115143711-4a0be4f48816 h1:8F+uUDbw/Qa192HXfxfoLf/RkVAhFLImTH6uYzhaLz8=
github.com/open-feature/schemas v0.2.9-0.20240115143711-4a0be4f48816/go.mod h1:5tZlsJkdP1CiBHWrGUbDQxpCAVNTG851yAbmUrfji1M=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

View File

@ -400,16 +400,38 @@ func getFlagdProperties(context map[string]any) (flagdProperties, bool) {
return p, true
}
func (je *JSON) loadAndCompileSchema() *gojsonschema.Schema {
schemaLoader := gojsonschema.NewSchemaLoader()
// compile dependency schema
targetingSchemaLoader := gojsonschema.NewStringLoader(schema.Targeting)
if err := schemaLoader.AddSchemas(targetingSchemaLoader); err != nil {
je.Logger.Warn(fmt.Sprintf("error adding Targeting schema: %s", err))
}
// compile root schema
flagdDefinitionsLoader := gojsonschema.NewStringLoader(schema.FlagdDefinitions)
compiledSchema, err := schemaLoader.Compile(flagdDefinitionsLoader)
if err != nil {
je.Logger.Warn(fmt.Sprintf("error compiling FlagdDefinitions schema: %s", err))
}
return compiledSchema
}
// configToFlags convert string configurations to flags and store them to pointer newFlags
func (je *JSON) configToFlags(config string, newFlags *Flags) error {
schemaLoader := gojsonschema.NewStringLoader(schema.FlagdDefinitions)
compiledSchema := je.loadAndCompileSchema()
flagStringLoader := gojsonschema.NewStringLoader(config)
result, err := gojsonschema.Validate(schemaLoader, flagStringLoader)
result, err := compiledSchema.Validate(flagStringLoader)
if err != nil {
return fmt.Errorf("error validating json schema: %w", err)
je.Logger.Warn(fmt.Sprintf("failed to execute JSON schema validation: %s", err))
} else if !result.Valid() {
return fmt.Errorf("JSON schema validation failed: %s", buildErrorString(result.Errors()))
je.Logger.Warn(fmt.Sprintf(
"flag definition does not conform to the schema; validation errors: %s", buildErrorString(result.Errors()),
))
}
transposedConfig, err := je.transposeEvaluators(config)

View File

@ -973,6 +973,112 @@ func TestState_Evaluator(t *testing.T) {
inputSyncType: sync.ALL,
expectedError: true,
},
"invalid targeting": {
inputState: `
{
"flags": {
"fibAlgo": {
"variants": {
"recursive": "recursive",
"memo": "memo",
"loop": "loop",
"binet": "binet"
},
"defaultVariant": "recursive",
"state": "ENABLED",
"source":"",
"targeting": {
"if": [
{
"in": ["@faas.com", {
"var": ["email"]
}]
}, "binet", "null", "loop"
]
}
},
"isColorYellow": {
"state": "ENABLED",
"variants": {
"on": true,
"off": false
},
"defaultVariant": "off",
"source":"",
"targeting": {
"if": [
{
"==": [
{
"varr": ["color"]
},
"yellow"
]
},
"on",
"off",
"none"
]
}
}
},
"flagSources":null
}
`,
inputSyncType: sync.ALL,
expectedError: false,
expectedOutputState: `
{
"flags": {
"fibAlgo": {
"variants": {
"recursive": "recursive",
"memo": "memo",
"loop": "loop",
"binet": "binet"
},
"defaultVariant": "recursive",
"state": "ENABLED",
"source":"",
"targeting": {
"if": [
{
"in": ["@faas.com", {
"var": ["email"]
}]
}, "binet", "null", "loop"
]
}
},
"isColorYellow": {
"state": "ENABLED",
"variants": {
"on": true,
"off": false
},
"defaultVariant": "off",
"source":"",
"targeting": {
"if": [
{
"==": [
{
"varr": ["color"]
},
"yellow"
]
},
"on",
"off",
"none"
]
}
}
},
"flagSources":null
}
`,
},
"empty evaluator": {
inputState: `
{

View File

@ -56,9 +56,7 @@
{
"==": [
{
"var": [
"color"
]
"var": ["color"]
},
"yellow"
]
@ -81,7 +79,9 @@
"if": [
{
"$ref": "emailWithFaas"
}, "binet", null
},
"binet",
null
]
}
},
@ -100,35 +100,27 @@
"$ref": "emailWithFaas"
},
{
"fractionalEvaluation": [
"email",
[
"red",
25
],
[
"blue",
25
],
[
"green",
25
],
[
"yellow",
25
]
"fractional": [
{ "var": "email" },
["red", 25],
["blue", 25],
["green", 25],
["yellow", 25]
]
}, null
},
null
]
}
}
},
"$evaluators": {
"emailWithFaas": {
"in": ["@faas.com", {
"var": ["email"]
}]
"in": [
"@faas.com",
{
"var": ["email"]
}
]
}
}
}

View File

@ -69,8 +69,9 @@ flags:
targeting:
if:
- "$ref": emailWithFaas
- fractionalEvaluation:
- email
- fractional:
- var:
- email
- - red
- 25
- - blue

View File

@ -56,9 +56,7 @@
{
"==": [
{
"var": [
"color"
]
"var": ["color"]
},
"yellow"
]
@ -81,7 +79,9 @@
"if": [
{
"$ref": "emailWithFaas"
}, "binet", null
},
"binet",
null
]
}
},
@ -100,35 +100,27 @@
"$ref": "emailWithFaas"
},
{
"fractionalEvaluation": [
"email",
[
"red",
25
],
[
"blue",
25
],
[
"green",
25
],
[
"yellow",
25
]
"fractional": [
{ "var": "email" },
["red", 25],
["blue", 25],
["green", 25],
["yellow", 25]
]
}, null
},
null
]
}
}
},
"$evaluators": {
"emailWithFaas": {
"in": ["@faas.com", {
"var": ["email"]
}]
"in": [
"@faas.com",
{
"var": ["email"]
}
]
}
}
}

View File

@ -69,8 +69,9 @@ flags:
targeting:
if:
- "$ref": emailWithFaas
- fractionalEvaluation:
- email
- fractional:
- var:
- email
- - red
- 25
- - blue

@ -1 +1 @@
Subproject commit f3e419c5ea676b6e0a4384b1ba3c9ad43b047eed
Subproject commit 4a0be4f48816ea0ac83d909ae58b8dcf5acda4b8