Repository: datreeio/datree
Pull request #622 (2022-05-15 14:53:38)

feat: validate yaml send result data


Patch:
diff --git a/bl/evaluation/evaluator.go b/bl/evaluation/evaluator.go
index cfcc862..d0a4378 100644
--- a/bl/evaluation/evaluator.go
+++ b/bl/evaluation/evaluator.go
@@ -11,6 +11,7 @@ import (
 	"github.com/datreeio/datree/pkg/cliClient"
 	"github.com/datreeio/datree/pkg/extractor"
 	"github.com/datreeio/datree/pkg/jsonSchemaValidator"
+	"github.com/datreeio/datree/pkg/utils"
 )
 
 const (
@@ -70,7 +71,7 @@ type EvaluationRequestData struct {
 	EvaluationDurationSeconds float64
 }
 
-var OSInfoFn = NewOSInfo
+var OSInfoFn = utils.NewOSInfo
 
 func (e *Evaluator) SendEvaluationResult(evaluationRequestData EvaluationRequestData) (*cliClient.SendEvaluationResultsResponse, error) {
 	osInfo := OSInfoFn()
diff --git a/cmd/root.go b/cmd/root.go
index eec0167..4f50b46 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -93,9 +93,12 @@ func NewRootCommand(app *App) *cobra.Command {
 	}))
 
 	rootCmd.AddCommand(validateYaml.New(&validateYaml.ValidateYamlCommandContext{
-		Printer:   app.Context.Printer,
-		Reader:    app.Context.Reader,
-		Extractor: app.Context.FilesExtractor,
+		Printer:     app.Context.Printer,
+		Reader:      app.Context.Reader,
+		Extractor:   app.Context.FilesExtractor,
+		CliClient:   app.Context.CliClient,
+		CliVersion:  CliVersion,
+		LocalConfig: app.Context.LocalConfig,
 	}))
 	return rootCmd
 }
diff --git a/cmd/validate-yaml/main.go b/cmd/validate-yaml/main.go
index 0db865c..2bdecb1 100644
--- a/cmd/validate-yaml/main.go
+++ b/cmd/validate-yaml/main.go
@@ -5,12 +5,19 @@ import (
 	"fmt"
 	"strings"
 
+	"github.com/datreeio/datree/pkg/cliClient"
 	pkgExtractor "github.com/datreeio/datree/pkg/extractor"
+	"github.com/datreeio/datree/pkg/localConfig"
 	"github.com/datreeio/datree/pkg/utils"
 	"github.com/datreeio/datree/pkg/yamlValidator"
 	"github.com/spf13/cobra"
 )
 
+const (
+	STATUS_PASSED = "passed"
+	STATUS_FAILED = "failed"
+)
+
 type IReader interface {
 	FilterFiles(paths []string) ([]string, error)
 }
@@ -22,10 +29,21 @@ type IPrinter interface {
 	PrintMessage(messageText string, messageColor string)
 }
 
+type ICliClient interface {
+	SendValidateYamlResult(request *cliClient.ValidatedYamlResult)
+}
+
+type ILocalConfig interface {
+	GetLocalConfiguration() (*localConfig.LocalConfig, error)
+}
+
 type ValidateYamlCommandContext struct {
-	Printer   IPrinter
-	Reader    IReader
-	Extractor yamlValidator.IExtractor
+	Printer     IPrinter
+	Reader      IReader
+	Extractor   yamlValidator.IExtractor
+	CliClient   ICliClient
+	LocalConfig ILocalConfig
+	CliVersion  string
 }
 
 var YamlNotValidError = errors.New("")
@@ -79,7 +97,11 @@ func New(ctx *ValidateYamlCommandContext) *cobra.Command {
 			invalidYamlFiles := newYamlValidator.ValidateFiles(filesPaths)
 			PrintValidationResults(ctx.Printer, invalidYamlFiles, filesCount)
 
-			if len(invalidYamlFiles) > 0 {
+			isValid := len(invalidYamlFiles) == 0
+
+			SendResults(ctx.LocalConfig, ctx.CliClient, ctx.CliVersion, isValid, invalidYamlFiles, filesPaths)
+
+			if !isValid {
 				return YamlNotValidError
 			}
 
@@ -97,3 +119,52 @@ func PrintValidationResults(printer IPrinter, invalidFiles []*pkgExtractor.Inval
 	validFilesCount := filesCount - len(invalidFiles)
 	printer.PrintYamlValidationSummary(validFilesCount, filesCount)
 }
+
+func SendResults(localConfig ILocalConfig, client ICliClient, cliVersion string, isValid bool, invalidYamlFiles []*pkgExtractor.InvalidFile, filesPaths []string) {
+	osInfo := utils.NewOSInfo()
+	resultFiles := prepareValidationResults(invalidYamlFiles, filesPaths)
+	configData, err := localConfig.GetLocalConfiguration()
+
+	if err != nil {
+		return
+	}
+
+	status := STATUS_PASSED
+	if !isValid {
+		status = STATUS_FAILED
+	}
+	result := &cliClient.ValidatedYamlResult{
+		Token:    configData.Token,
+		ClientId: configData.ClientId,
+		Files:    resultFiles,
+		Status:   status,
+		Metadata: &cliClient.Metadata{
+			CliVersion:      cliVersion,
+			Os:              osInfo.OS,
+			KernelVersion:   osInfo.KernelVersion,
+			PlatformVersion: osInfo.PlatformVersion,
+		},
+	}
+
+	client.SendValidateYamlResult(result)
+}
+
+func prepareValidationResults(invalidFiles []*pkgExtractor.InvalidFile, filesPaths []string) []*cliClient.ValidatedFile {
+	var validationResults []*cliClient.ValidatedFile
+	filesMap := make(map[string]bool)
+
+	for _, filename := range filesPaths {
+		absoluteFilePath, _ := pkgExtractor.ToAbsolutePath(filename)
+		filesMap[absoluteFilePath] = true
+	}
+	for _, invalidFile := range invalidFiles {
+		filesMap[invalidFile.Path] = false
+	}
+	for filename, isValid := range filesMap {
+		validationResults = append(validationResults, &cliClient.ValidatedFile{
+			Path:    filename,
+			IsValid: isValid,
+		})
+	}
+	return validationResults
+}
diff --git a/pkg/cliClient/validateYamlResult.go b/pkg/cliClient/validateYamlResult.go
new file mode 100644
index 0000000..8d8e785
--- /dev/null
+++ b/pkg/cliClient/validateYamlResult.go
@@ -0,0 +1,26 @@
+package cliClient
+
+import (
+	"net/http"
+)
+
+type ValidatedFile struct {
+	Path    string `json:"path"`
+	IsValid bool   `json:"isValid"`
+}
+
+type ValidatedYamlResult struct {
+	Token    string           `json:"token"`
+	ClientId string           `json:"clientId"`
+	Metadata *Metadata        `json:"metadata"`
+	Files    []*ValidatedFile `json:"files"`
+	Status   string           `json:"status"`
+}
+
+func (c *CliClient) SendValidateYamlResult(request *ValidatedYamlResult) {
+	if c.networkValidator.IsLocalMode() {
+		return
+	}
+
+	_, _ = c.httpClient.Request(http.MethodPost, "/cli/yaml-validation/", request, c.flagsHeaders)
+}
diff --git a/bl/evaluation/osInfo.go b/pkg/utils/osInfo.go
similarity index 94%
rename from bl/evaluation/osInfo.go
rename to pkg/utils/osInfo.go
index 9d3541f..f55eb14 100644
--- a/bl/evaluation/osInfo.go
+++ b/pkg/utils/osInfo.go
@@ -1,4 +1,4 @@
-package evaluation
+package utils
 
 import "github.com/shirou/gopsutil/v3/host"
 


Test patch:
diff --git a/bl/evaluation/evaluator_test.go b/bl/evaluation/evaluator_test.go
index ec1cf16..780ba80 100644
--- a/bl/evaluation/evaluator_test.go
+++ b/bl/evaluation/evaluator_test.go
@@ -7,6 +7,7 @@ import (
 
 	policy_factory "github.com/datreeio/datree/bl/policy"
 	"github.com/datreeio/datree/pkg/fileReader"
+	"github.com/datreeio/datree/pkg/utils"
 
 	"github.com/datreeio/datree/pkg/ciContext"
 	"github.com/datreeio/datree/pkg/cliClient"
@@ -66,8 +67,8 @@ func TestSendEvaluationResult(t *testing.T) {
 			},
 		}
 
-		osInfo := &OSInfo{OS: "darwin", PlatformVersion: "1.2.3", KernelVersion: "4.5.6"}
-		OSInfoFn = func() *OSInfo {
+		osInfo := &utils.OSInfo{OS: "darwin", PlatformVersion: "1.2.3", KernelVersion: "4.5.6"}
+		OSInfoFn = func() *utils.OSInfo {
 			return osInfo
 		}
 
@@ -157,7 +158,6 @@ func TestEvaluate(t *testing.T) {
 
 type evaluateArgs struct {
 	policyCheckData PolicyCheckData
-	osInfo          *OSInfo
 }
 
 type evaluateExpected struct {
diff --git a/cmd/validate-yaml/main_test.go b/cmd/validate-yaml/main_test.go
index 4826885..9c1ac79 100644
--- a/cmd/validate-yaml/main_test.go
+++ b/cmd/validate-yaml/main_test.go
@@ -5,7 +5,9 @@ import (
 	"errors"
 	"testing"
 
+	"github.com/datreeio/datree/pkg/cliClient"
 	pkgExtractor "github.com/datreeio/datree/pkg/extractor"
+	"github.com/datreeio/datree/pkg/localConfig"
 	"github.com/datreeio/datree/pkg/yamlValidator"
 	"github.com/spf13/cobra"
 	"github.com/stretchr/testify/assert"
@@ -65,7 +67,25 @@ func (e *MockExtractor) ExtractConfigurationsFromYamlFile(path string) (*[]pkgEx
 	return configurations, args.String(1), invalidFile
 }
 
-func createMocks() (*MockFileReader, *MockPrinter, *MockExtractor) {
+type MockCliClient struct {
+	mock.Mock
+}
+
+func (cc *MockCliClient) SendValidateYamlResult(request *cliClient.ValidatedYamlResult) {
+	cc.Called(request)
+}
+
+type MockLocalConfig struct {
+	mock.Mock
+}
+
+func (lc *MockLocalConfig) GetLocalConfiguration() (*localConfig.LocalConfig, error) {
+	lc.Called()
+	localConfig := &localConfig.LocalConfig{}
+	return localConfig, nil
+}
+
+func createMocks() (*MockFileReader, *MockPrinter, *MockExtractor, *MockCliClient, *MockLocalConfig) {
 	mockedFileReader := &MockFileReader{}
 	mockedFileReader.On("FilterFiles", mock.Anything).Return([]string{"."}, nil)
 
@@ -78,21 +98,30 @@ func createMocks() (*MockFileReader, *MockPrinter, *MockExtractor) {
 	mockedExtractor := &MockExtractor{}
 	mockedExtractor.On("ExtractConfigurationsFromYamlFile", mock.Anything).Return(nil, "", nil)
 
-	return mockedFileReader, mockedPrinter, mockedExtractor
+	mockedCliClient := &MockCliClient{}
+	mockedCliClient.On("SendValidateYamlResult", mock.Anything).Return()
+
+	mockedLocalConfig := &MockLocalConfig{}
+	mockedLocalConfig.On("GetLocalConfiguration").Return(&localConfig.LocalConfig{}, nil)
+
+	return mockedFileReader, mockedPrinter, mockedExtractor, mockedCliClient, mockedLocalConfig
 }
 
-func createCommand(reader IReader, printer IPrinter, extractor yamlValidator.IExtractor) *cobra.Command {
+func createCommand(reader IReader, printer IPrinter, extractor yamlValidator.IExtractor, CliClient ICliClient, LocalConfig ILocalConfig, cliVersion string) *cobra.Command {
 	cmd := New(&ValidateYamlCommandContext{
-		Reader:    reader,
-		Printer:   printer,
-		Extractor: extractor,
+		Reader:      reader,
+		Printer:     printer,
+		Extractor:   extractor,
+		CliClient:   CliClient,
+		LocalConfig: LocalConfig,
+		CliVersion:  cliVersion,
 	})
 	return cmd
 }
 
 func TestNoFilesSelected(t *testing.T) {
-	mockedFileReader, mockedPrinter, mockedExtractor := createMocks()
-	cmd := createCommand(mockedFileReader, mockedPrinter, mockedExtractor)
+	mockedFileReader, mockedPrinter, mockedExtractor, mockedCliClient, mockedLocalConfig := createMocks()
+	cmd := createCommand(mockedFileReader, mockedPrinter, mockedExtractor, mockedCliClient, mockedLocalConfig, "")
 
 	cmd.SetArgs([]string{})
 	output := cmd.Execute()
@@ -111,8 +140,8 @@ func TestInvalidYaml(t *testing.T) {
 		},
 	})
 
-	mockedFileReader, mockedPrinter, _ := createMocks()
-	cmd := createCommand(mockedFileReader, mockedPrinter, mockedExtractor)
+	mockedFileReader, mockedPrinter, _, mockedCliClient, mockedLocalConfig := createMocks()
+	cmd := createCommand(mockedFileReader, mockedPrinter, mockedExtractor, mockedCliClient, mockedLocalConfig, "")
 
 	actual := new(bytes.Buffer)
 	cmd.SetOut(actual)
@@ -124,8 +153,8 @@ func TestInvalidYaml(t *testing.T) {
 }
 
 func TestValidYaml(t *testing.T) {
-	mockedFileReader, mockedPrinter, mockedExtractor := createMocks()
-	cmd := createCommand(mockedFileReader, mockedPrinter, mockedExtractor)
+	mockedFileReader, mockedPrinter, mockedExtractor, mockedCliClient, mockedLocalConfig := createMocks()
+	cmd := createCommand(mockedFileReader, mockedPrinter, mockedExtractor, mockedCliClient, mockedLocalConfig, "")
 
 	actual := new(bytes.Buffer)
 	cmd.SetOut(actual)