Skip to content

Commit 9ab873d

Browse files
committed
Add allowLink option into the spec
1 parent e03cb61 commit 9ab873d

File tree

14 files changed

+39
-161
lines changed

14 files changed

+39
-161
lines changed

code/go/internal/specschema/folder_item_spec.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ func (s *ItemSpec) DevelopmentFolder() bool {
8181
return s.itemSpec.DevelopmentFolder
8282
}
8383

84+
// AllowLink returns true if the item allows links.
85+
func (s *ItemSpec) AllowLink() bool {
86+
return s.itemSpec.AllowLink
87+
}
88+
8489
// ForbiddenPatterns returns the list of forbidden patterns for the name of this item.
8590
func (s *ItemSpec) ForbiddenPatterns() []string {
8691
return s.itemSpec.ForbiddenPatterns
@@ -135,6 +140,7 @@ type folderItemSpec struct {
135140
AdditionalContents bool `json:"additionalContents" yaml:"additionalContents"`
136141
Contents []*folderItemSpec `json:"contents" yaml:"contents"`
137142
DevelopmentFolder bool `json:"developmentFolder" yaml:"developmentFolder"`
143+
AllowLink bool `json:"allowLink" yaml:"allowLink"`
138144

139145
// As it is required to be inline both in yaml and json, this struct must be public embedded field
140146
SpecLimits `yaml:",inline"`

code/go/internal/spectypes/item.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ type ItemSpec interface {
5757
// DevelopmentFolder returns true if the item is inside a development folder.
5858
DevelopmentFolder() bool
5959

60+
// AllowLink returns true if the item allows links.
61+
AllowLink() bool
62+
6063
// ForbiddenPatterns returns the list of forbidden patterns for the name of this item.
6164
ForbiddenPatterns() []string
6265

code/go/internal/validator/folder_item_spec.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ import (
1616
func matchingFileExists(spec spectypes.ItemSpec, files []fs.DirEntry) (bool, error) {
1717
if spec.Name() != "" {
1818
for _, file := range files {
19-
if file.Name() == spec.Name() {
19+
_, fileName := checkLink(file.Name())
20+
if fileName == spec.Name() {
2021
return spec.IsDir() == file.IsDir(), nil
2122
}
2223
}
2324
} else if spec.Pattern() != "" {
2425
for _, file := range files {
25-
isMatch, err := regexp.MatchString(spec.Pattern(), file.Name())
26+
_, fileName := checkLink(file.Name())
27+
isMatch, err := regexp.MatchString(spec.Pattern(), fileName)
2628
if err != nil {
2729
return false, fmt.Errorf("invalid folder item spec pattern: %w", err)
2830
}

code/go/internal/validator/folder_spec.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ func (v *validator) Validate() specerrors.ValidationErrors {
190190
}
191191

192192
func (v *validator) findItemSpec(folderItemName string) (spectypes.ItemSpec, error) {
193+
isLink, folderItemName := checkLink(folderItemName)
193194
for _, itemSpec := range v.spec.Contents() {
194195
if itemSpec.Name() != "" && itemSpec.Name() == folderItemName {
195196
return itemSpec, nil
@@ -213,6 +214,9 @@ func (v *validator) findItemSpec(folderItemName string) (spectypes.ItemSpec, err
213214
}
214215

215216
if !isForbidden {
217+
if isLink && !itemSpec.AllowLink() {
218+
return nil, fmt.Errorf("item [%s] is a link but is not allowed", folderItemName)
219+
}
216220
return itemSpec, nil
217221
}
218222
}
@@ -222,3 +226,13 @@ func (v *validator) findItemSpec(folderItemName string) (spectypes.ItemSpec, err
222226
// No item spec found
223227
return nil, nil
224228
}
229+
230+
// checkLink checks if an item is a link and returns the item name without the
231+
// ".link" suffix if it is a link.
232+
func checkLink(itemName string) (bool, string) {
233+
const linkExtension = ".link"
234+
if strings.HasSuffix(itemName, linkExtension) {
235+
return true, strings.TrimSuffix(itemName, linkExtension)
236+
}
237+
return false, itemName
238+
}

code/go/internal/validator/semantic/validate_anyof_required_contents.go

Lines changed: 0 additions & 96 deletions
This file was deleted.

code/go/internal/validator/spec.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ func (s Spec) rules(pkgType string, rootSpec spectypes.ItemSpec) validationRules
214214
{fn: semantic.ValidateDimensionsPresent, types: []string{"integration"}, since: semver.MustParse("3.0.1")},
215215
{fn: semantic.ValidateCapabilitiesRequired, since: semver.MustParse("2.10.0")}, // capabilities definition was added in spec version 2.10.0
216216
{fn: semantic.ValidateRequiredVarGroups},
217-
{fn: semantic.ValidateAnyOfRequiredContents},
218217
}
219218

220219
var validationRules validationRules

code/go/pkg/linkedfiles/fs.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ func NewLinksFS(workDir string, inner fs.FS) *LinksFS {
3030

3131
// Open opens a file in the filesystem.
3232
func (lfs *LinksFS) Open(name string) (fs.File, error) {
33-
if filepath.Ext(name) != LinkExtension {
33+
const linkExtension = ".link"
34+
if filepath.Ext(name) != linkExtension {
3435
return lfs.inner.Open(name)
3536
}
3637
pathName := filepath.Join(lfs.workDir, name)

code/go/pkg/linkedfiles/linkedfiles.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ import (
1616
"strings"
1717
)
1818

19-
// LinkExtension is the file extension for linked files.
20-
const LinkExtension = ".link"
21-
2219
// A Link represents a linked file.
2320
// It contains the path to the link file, the checksum of the linked file,
2421
// the path to the target file, and the checksum of the included file contents.

code/go/pkg/validator/validator_test.go

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -814,41 +814,6 @@ func TestValidateForbiddenDataStreamName(t *testing.T) {
814814
}
815815
}
816816

817-
func TestValidateAnyOfContents(t *testing.T) {
818-
tests := map[string][]string{
819-
"missing_required_files": {
820-
"item [.keep] is not allowed in folder [../../../../test/packages/missing_required_files/agent/input]",
821-
"item [.keep] is not allowed in folder [../../../../test/packages/missing_required_files/data_stream/foo/agent/stream]",
822-
"item [.keep] is not allowed in folder [../../../../test/packages/missing_required_files/data_stream/foo/elasticsearch/ingest_pipeline]",
823-
"item [.keep] is not allowed in folder [../../../../test/packages/missing_required_files/data_stream/foo/fields]",
824-
`path "agent/input": no file matching any of the patterns [*.yml.hbs *.yml.hbs.link] found in agent/input`,
825-
`data stream "foo": no file matching any of the patterns [*.yml.hbs *.yml.hbs.link] found in data_stream/foo/agent/stream`,
826-
`data stream "foo": no file matching any of the patterns [*.yml *.yml.link] found in data_stream/foo/fields`,
827-
`path "elasticsearch/ingest_pipeline": no file matching any of the patterns [*.yml *.json *.yml.link *.json.link] found in elasticsearch/ingest_pipeline`,
828-
`data stream "foo": no file matching any of the patterns [*.yml *.json *.yml.link *.json.link] found in data_stream/foo/elasticsearch/ingest_pipeline`,
829-
},
830-
}
831-
832-
for pkgName, expectedErrorMessages := range tests {
833-
t.Run(pkgName, func(t *testing.T) {
834-
err := ValidateFromPath(path.Join("..", "..", "..", "..", "test", "packages", pkgName))
835-
if len(expectedErrorMessages) == 0 {
836-
assert.NoError(t, err)
837-
return
838-
}
839-
assert.Error(t, err)
840-
841-
errs, ok := err.(specerrors.ValidationErrors)
842-
require.True(t, ok)
843-
assert.Len(t, errs, len(expectedErrorMessages))
844-
845-
for _, foundError := range errs {
846-
require.Contains(t, expectedErrorMessages, foundError.Error())
847-
}
848-
})
849-
}
850-
}
851-
852817
func requireErrorMessage(t *testing.T, pkgName string, invalidItemsPerFolder map[string][]string, expectedErrorMessage string) {
853818
pkgRootPath := filepath.Join("..", "..", "..", "..", "test", "packages", pkgName)
854819

spec/integration/agent/spec.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,5 @@ spec:
1111
type: file
1212
sizeLimit: 2MB
1313
pattern: '^.+\.yml\.hbs$'
14-
required: false
15-
- description: Link to a config template file for inputs defined in the policy_templates section of the top level manifest
16-
type: file
17-
pattern: '^.+\.yml\.hbs\.link$'
18-
required: false
14+
required: true
15+
allowLink: true

0 commit comments

Comments
 (0)