Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate JSON properties with relative-path format #83

Merged
merged 5 commits into from
Nov 19, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/go/internal/spec/statik.go

Large diffs are not rendered by default.

23 changes: 22 additions & 1 deletion code/go/internal/validator/folder_item_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"regexp"
"sync"

"github.com/pkg/errors"
"github.com/xeipuuv/gojsonschema"
Expand All @@ -26,6 +27,8 @@ type folderItemSpec struct {
commonSpec `yaml:",inline"`
}

var formatCheckersMutex sync.Mutex

func (s *folderItemSpec) matchingFileExists(files []os.FileInfo) (bool, error) {
if s.Name != "" {
for _, file := range files {
Expand Down Expand Up @@ -78,6 +81,14 @@ func (s *folderItemSpec) validate(fs http.FileSystem, folderSpecPath string, ite

// validation with schema
documentLoader := gojsonschema.NewBytesLoader(itemData)

formatCheckersMutex.Lock()
defer func() {
unloadRelativePathFormatChecker()
formatCheckersMutex.Unlock()
}()

loadRelativePathFormatChecker(filepath.Dir(itemPath))
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
if err != nil {
return ValidationErrors{err}
Expand All @@ -89,7 +100,17 @@ func (s *folderItemSpec) validate(fs http.FileSystem, folderSpecPath string, ite

var errs ValidationErrors
for _, re := range result.Errors() {
errs = append(errs, fmt.Errorf("field %s: %s", re.Field(), re.Description()))
errs = append(errs, fmt.Errorf("field %s: %s", re.Field(), adjustErrorDescription(re.Description())))
}
return errs
}

func loadRelativePathFormatChecker(currentPath string) {
gojsonschema.FormatCheckers.Add("relative-path", RelativePathChecker{
Copy link
Contributor

@ycombinator ycombinator Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making relative-path a constant, now that we are using it in a few places in code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

currentPath: currentPath,
})
}

func unloadRelativePathFormatChecker() {
gojsonschema.FormatCheckers.Remove("relative-path")
}
8 changes: 8 additions & 0 deletions code/go/internal/validator/folder_item_spec_errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package validator

func adjustErrorDescription(description string) string {
if description == "Does not match format 'relative-path'" {
return "relative path is invalid or target doesn't exist"
}
return description
}
26 changes: 26 additions & 0 deletions code/go/internal/validator/folder_item_spec_format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package validator

import (
"os"
"path/filepath"
)

// RelativePathChecker is responsible for checking presence of the file path
type RelativePathChecker struct {
currentPath string
}

// IsFormat method checks if the path exists.
func (r RelativePathChecker) IsFormat(input interface{}) bool {
asString, ok := input.(string)
if !ok {
return false
}

path := filepath.Join(r.currentPath, asString)
_, err := os.Stat(path)
if err != nil {
return false
}
return true
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 15 additions & 1 deletion code/go/internal/validator/test/packages/good/manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,18 @@ policy_templates:
default:
- http://127.0.0.1
owner:
github: elastic/foobar
github: elastic/foobar
screenshots:
- src: /img/kibana-system.png
title: kibana system
size: 1220x852
type: image/png
- src: /img/metricbeat_system_dashboard.png
title: metricbeat system dashboard
size: 2097x1933
type: image/png
icons:
- src: /img/system.svg
title: system
size: 1000x1000
type: image/svg+xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
- name: source
title: Source
group: 2
type: group
fields:
- name: geo.city_name
level: core
type: keyword
description: City name.
ignore_above: 1024
- name: geo.location
level: core
type: geo_point
description: Longitude and latitude.
- name: geo.region_iso_code
level: core
type: keyword
description: Region ISO code.
ignore_above: 1024
- name: geo.region_name
level: core
type: keyword
description: Region name.
ignore_above: 1024
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
title: pe sample
type: logs
release: experimental
streams:
- input: logfile
vars:
- name: paths
type: text
title: Paths
multi: true
required: true
show_user: true
default:
- /var/log/nginx/access.log*
- name: server_status_path
type: text
title: Server Status Path
multi: false
required: true
show_user: false
default: /server-status
title: Nginx access logs
description: Collect Nginx access logs
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
format_version: 1.0.4
name: missing_image_files
title: Missing Image Files
description: This package is bad.
version: 0.1.2
release: beta
conditions:
kibana.version: '^7.9.0'
policy_templates:
- name: apache
title: Apache logs and metrics
description: Collect logs and metrics from Apache instances
inputs:
- type: apache/metrics
title: Collect metrics from Apache instances
description: Collecting Apache status metrics
vars:
- name: hosts
type: text
title: Hosts
multi: true
required: true
show_user: true
default:
- http://127.0.0.1
owner:
github: elastic/foobar
screenshots:
- src: /img/kibana-system-wrong.png
title: kibana system
size: 1220x852
type: image/png
- src: /img/metricbeat_system_dashboard.png
title: metricbeat system dashboard
size: 2097x1933
type: image/png
icons:
- src: /img/system-wrong.svg
title: system
size: 1000x1000
type: image/svg+xml
- src: /img/system.svg
title: system
size: 1000x1000
type: image/svg+xml
19 changes: 16 additions & 3 deletions code/go/pkg/validator/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ func TestValidateFile(t *testing.T) {
"document dashes are required (start the document with '---')",
},
},
"missing_image_files": {
"manifest.yml",
[]string{
"field screenshots.0.src: relative path is invalid or target doesn't exist",
"field icons.0.src: relative path is invalid or target doesn't exist",
},
},
}

for pkgName, test := range tests {
Expand All @@ -45,9 +52,15 @@ func TestValidateFile(t *testing.T) {
require.Len(t, errs, len(test.expectedErrContains))
vErrs, ok := errs.(validator.ValidationErrors)
require.True(t, ok)
for idx, err := range vErrs {
expectedErr := errPrefix + test.expectedErrContains[idx]
require.Contains(t, err.Error(), expectedErr)

var errMessages []string
for _, vErr := range vErrs {
errMessages = append(errMessages, vErr.Error())
}

for _, expectedErrMessage := range test.expectedErrContains {
expectedErr := errPrefix + expectedErrMessage
require.Contains(t, errMessages, expectedErr)
}
}
})
Expand Down
2 changes: 2 additions & 0 deletions versions/1/manifest.spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ spec:
src:
description: Relative path to the icon's image file.
type: string
format: relative-path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be documented in CONTRIBUTING.md for anyone who wants to add elements to the spec in the future that could use relative-path validation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

examples:
- "/img/logo_apache.svg"
title:
Expand Down Expand Up @@ -143,6 +144,7 @@ spec:
src:
description: Relative path to the scrennshot's image file.
type: string
format: relative-path
examples:
- "/img/apache_httpd_server_status.png"
title:
Expand Down