Repository: datreeio/datree
Pull request #525 (2022-03-23 14:09:13)

fix: publishing custom rules using jsonSchema fails in datree test


Patch:
diff --git a/bl/policy/policy_factory.go b/bl/policy/policy_factory.go
index 092830e..9e89593 100644
--- a/bl/policy/policy_factory.go
+++ b/bl/policy/policy_factory.go
@@ -2,6 +2,7 @@ package policy
 
 import (
 	_ "embed"
+	"encoding/json"
 	"fmt"
 
 	"github.com/datreeio/datree/pkg/cliClient"
@@ -16,7 +17,7 @@ type Policy struct {
 type RuleWithSchema struct {
 	RuleIdentifier   string
 	RuleName         string
-	Schema           map[string]interface{}
+	Schema           interface{}
 	MessageOnFailure string
 }
 
@@ -72,7 +73,16 @@ func populateRules(policyRules []cliClient.Rule, customRules []*cliClient.Custom
 		customRule := getCustomRuleByIdentifier(customRules, rule.Identifier)
 
 		if customRule != nil {
-			rules = append(rules, RuleWithSchema{rule.Identifier, customRule.Name, customRule.Schema, rule.MessageOnFailure})
+			if customRule.Schema == nil {
+				schema := make(map[string]interface{})
+				err := json.Unmarshal([]byte(customRule.JsonSchema), &schema)
+				if err != nil {
+					return nil, err
+				}
+				rules = append(rules, RuleWithSchema{rule.Identifier, customRule.Name, schema, rule.MessageOnFailure})
+			} else {
+				rules = append(rules, RuleWithSchema{rule.Identifier, customRule.Name, customRule.Schema, rule.MessageOnFailure})
+			}
 		} else {
 			defaultRule := getDefaultRuleByIdentifier(defaultRules, rule.Identifier)
 
diff --git a/internal/fixtures/policyAsCode/prerun.json b/internal/fixtures/policyAsCode/prerun.json
index c86ae08..c5526da 100644
--- a/internal/fixtures/policyAsCode/prerun.json
+++ b/internal/fixtures/policyAsCode/prerun.json
@@ -23,6 +23,28 @@
             }
           }
         }
+      },
+      {
+        "identifier": "UNIQUE2",
+        "name": "rule unique 2",
+        "defaultMessageOnFailure": "default message for rule fail number 2",
+        "jsonSchema": "{\"type\":\"object\",\"properties\":{\"apiVersion\":{\"type\":\"string\"}},\"required\":[\"apiVersion\"]}"
+      },
+      {
+        "identifier": "UNIQUE3",
+        "name": "rule unique 3",
+        "defaultMessageOnFailure": "default message for rule fail number 3",
+        "schema": {
+          "properties": {
+            "apiVersion": {
+              "type": "string"
+            }
+          },
+          "required": [
+            "apiVersion"
+          ],
+          "type": "object"
+        }
       }
     ],
     "policies": [
@@ -52,6 +74,19 @@
             "messageOnFailure": "All lables values must follow the RFC 1123 hostname standard (https://knowledge.broadcom.com/external/article/49542/restrictions-on-valid-host-names.html)"
           }
         ]
+      },
+      {
+        "name": "labels_best_practices3",
+        "rules": [
+          {
+            "identifier": "UNIQUE2",
+            "messageOnFailure": "default message for rule fail number 2"
+          },
+          {
+            "identifier": "UNIQUE3",
+            "messageOnFailure": "default message for rule fail number 3"
+          }
+        ]
       }
     ]
   },
diff --git a/pkg/cliClient/evaluation.go b/pkg/cliClient/evaluation.go
index bbbafe8..45c20ad 100644
--- a/pkg/cliClient/evaluation.go
+++ b/pkg/cliClient/evaluation.go
@@ -67,10 +67,11 @@ type EvaluationRequest struct {
 }
 
 type CustomRule struct {
-	Identifier              string                 `json:"identifier"`
-	Name                    string                 `json:"name"`
-	DefaultMessageOnFailure string                 `json:"defaultMessageOnFailure"`
-	Schema                  map[string]interface{} `json:"schema"`
+	Identifier              string      `json:"identifier"`
+	Name                    string      `json:"name"`
+	DefaultMessageOnFailure string      `json:"defaultMessageOnFailure"`
+	Schema                  interface{} `json:"schema"`
+	JsonSchema              string      `json:"jsonSchema"`
 }
 
 type Rule struct {


Test patch:
diff --git a/bl/policy/policy_factory_test.go b/bl/policy/policy_factory_test.go
index cf1d6fc..9d5689d 100644
--- a/bl/policy/policy_factory_test.go
+++ b/bl/policy/policy_factory_test.go
@@ -78,6 +78,25 @@ func TestCreatePolicy(t *testing.T) {
 
 		assert.Equal(t, expectedPolicy, policy)
 	})
+
+	t.Run("Test Create Policy With Custom Rules", func(t *testing.T) {
+		policy, err := CreatePolicy(policiesJson.PoliciesJson, "labels_best_practices3")
+		var expectedRules []RuleWithSchema
+		if err != nil {
+			panic(err)
+		}
+
+		jsonSchemaStr := "{\"type\":\"object\",\"properties\":{\"apiVersion\":{\"type\":\"string\"}},\"required\":[\"apiVersion\"]}"
+		customRuleJsonSchema := make(map[string]interface{})
+		err = json.Unmarshal([]byte(jsonSchemaStr), &customRuleJsonSchema)
+		if err != nil {
+			panic(err)
+		}
+		expectedRules = append(expectedRules, RuleWithSchema{RuleIdentifier: "UNIQUE2", RuleName: "rule unique 2", Schema: customRuleJsonSchema, MessageOnFailure: "default message for rule fail number 2"})
+		expectedRules = append(expectedRules, RuleWithSchema{RuleIdentifier: "UNIQUE3", RuleName: "rule unique 3", Schema: customRuleJsonSchema, MessageOnFailure: "default message for rule fail number 3"})
+
+		assert.Equal(t, expectedRules, policy.Rules)
+	})
 }
 
 func mockGetPreRunData() *cliClient.EvaluationPrerunDataResponse {