Skip to content

Commit 18633cc

Browse files
committed
Merge branch 'main' into 970-new-agent-version-condition
2 parents 49363fe + 1c98376 commit 18633cc

35 files changed

+764
-2
lines changed

.buildkite/pipeline.test-with-integrations-repo.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
env:
2-
SETUP_GVM_VERSION: 'v0.5.1' # https://github.com/andrewkroh/gvm/issues/44#issuecomment-1013231151
2+
SETUP_GVM_VERSION: 'v0.6.0' # https://github.com/andrewkroh/gvm/issues/44#issuecomment-1013231151
33
GO_LINUX_AGENT_IMAGE: "golang:${GO_VERSION}"
44
GH_CLI_VERSION: "2.29.0"
55
JQ_VERSION: "1.7"

.buildkite/pipeline.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json
22

33
env:
4-
SETUP_GVM_VERSION: 'v0.5.1' # https://github.com/andrewkroh/gvm/issues/44#issuecomment-1013231151
4+
SETUP_GVM_VERSION: 'v0.6.0' # https://github.com/andrewkroh/gvm/issues/44#issuecomment-1013231151
55
SETUP_MAGE_VERSION: "latest"
66
DOCKER_COMPOSE_VERSION: "v2.17.2"
77
GO_LINUX_AGENT_IMAGE: "golang:${GO_VERSION}"
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package semantic
6+
7+
import (
8+
"errors"
9+
"fmt"
10+
"io/fs"
11+
"os"
12+
"path"
13+
14+
"gopkg.in/yaml.v3"
15+
16+
"github.com/elastic/package-spec/v3/code/go/internal/fspath"
17+
"github.com/elastic/package-spec/v3/code/go/pkg/specerrors"
18+
)
19+
20+
const (
21+
inputPackageType string = "input"
22+
)
23+
24+
var (
25+
errRequiredTemplatePath = errors.New("template_path is required for input type packages")
26+
errFailedToReadManifest = errors.New("failed to read manifest")
27+
errFailedToParseManifest = errors.New("failed to parse manifest")
28+
errTemplateNotFound = errors.New("template file not found")
29+
errInvalidPackageType = errors.New("invalid package type")
30+
)
31+
32+
type inputPolicyTemplate struct {
33+
Name string `yaml:"name"`
34+
TemplatePath string `yaml:"template_path"` // input type packages require this field
35+
}
36+
37+
type inputPackageManifest struct { // package manifest
38+
Type string `yaml:"type"`
39+
PolicyTemplates []inputPolicyTemplate `yaml:"policy_templates"`
40+
}
41+
42+
// ValidateInputPackagesPolicyTemplates validates the policy template entries of an input package
43+
func ValidateInputPackagesPolicyTemplates(fsys fspath.FS) specerrors.ValidationErrors {
44+
var errs specerrors.ValidationErrors
45+
46+
manifestPath := "manifest.yml"
47+
data, err := fs.ReadFile(fsys, manifestPath)
48+
if err != nil {
49+
return specerrors.ValidationErrors{
50+
specerrors.NewStructuredErrorf("file \"%s\" is invalid: %ww", fsys.Path(manifestPath), errFailedToReadManifest)}
51+
}
52+
53+
var manifest inputPackageManifest
54+
err = yaml.Unmarshal(data, &manifest)
55+
if err != nil {
56+
return specerrors.ValidationErrors{
57+
specerrors.NewStructuredErrorf("file \"%s\" is invalid: %w", fsys.Path(manifestPath), errFailedToParseManifest)}
58+
}
59+
60+
if manifest.Type != inputPackageType {
61+
return specerrors.ValidationErrors{
62+
specerrors.NewStructuredErrorf("file \"%s\" is invalid: expected package type \"%s\", got \"%s\": %w",
63+
fsys.Path(manifestPath), inputPackageType, manifest.Type, errInvalidPackageType)}
64+
}
65+
66+
for _, policyTemplate := range manifest.PolicyTemplates {
67+
err := validateInputPackagePolicyTemplate(fsys, policyTemplate)
68+
if err != nil {
69+
errs = append(errs, specerrors.NewStructuredErrorf(
70+
"file \"%s\" is invalid: policy template \"%s\" references template_path \"%s\": %w",
71+
fsys.Path(manifestPath), policyTemplate.Name, policyTemplate.TemplatePath, err))
72+
}
73+
}
74+
75+
return errs
76+
}
77+
78+
// validateInputPackagePolicyTemplate validates the template_path at the policy template level for input type packages
79+
// if the template_path is empty, it returns an error as this field is required for input type packages
80+
func validateInputPackagePolicyTemplate(fsys fspath.FS, policyTemplate inputPolicyTemplate) error {
81+
if policyTemplate.TemplatePath == "" {
82+
return errRequiredTemplatePath
83+
}
84+
return validateAgentInputTemplatePath(fsys, policyTemplate.TemplatePath)
85+
}
86+
87+
func validateAgentInputTemplatePath(fsys fspath.FS, tmplPath string) error {
88+
templatePath := path.Join("agent", "input", tmplPath)
89+
_, err := fs.Stat(fsys, templatePath)
90+
if err != nil {
91+
if errors.Is(err, os.ErrNotExist) {
92+
return errTemplateNotFound
93+
}
94+
return fmt.Errorf("failed to stat template file %s: %w", fsys.Path(templatePath), err)
95+
}
96+
97+
return nil
98+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package semantic
6+
7+
import (
8+
"os"
9+
"path/filepath"
10+
"testing"
11+
12+
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/require"
14+
15+
"github.com/elastic/package-spec/v3/code/go/internal/fspath"
16+
)
17+
18+
func TestValidateInputPackagesPolicyTemplates(t *testing.T) {
19+
20+
t.Run("policy_templates_have_template_path", func(t *testing.T) {
21+
d := t.TempDir()
22+
23+
err := os.MkdirAll(filepath.Join(d, "agent", "input"), 0o755)
24+
require.NoError(t, err)
25+
err = os.WriteFile(filepath.Join(d, "manifest.yml"), []byte(`
26+
type: input
27+
policy_templates:
28+
- name: udp
29+
template_path: udp.yml.hbs
30+
`), 0o644)
31+
require.NoError(t, err)
32+
err = os.WriteFile(filepath.Join(d, "agent", "input", "udp.yml.hbs"), []byte("# UDP template"), 0o644)
33+
require.NoError(t, err)
34+
35+
errs := ValidateInputPackagesPolicyTemplates(fspath.DirFS(d))
36+
require.Empty(t, errs, "expected no validation errors")
37+
38+
})
39+
40+
t.Run("policy_templates_empty_template_path", func(t *testing.T) {
41+
d := t.TempDir()
42+
43+
err := os.MkdirAll(filepath.Join(d, "agent", "input"), 0o755)
44+
require.NoError(t, err)
45+
err = os.WriteFile(filepath.Join(d, "manifest.yml"), []byte(`
46+
type: input
47+
policy_templates:
48+
- name: udp
49+
`), 0o644)
50+
require.NoError(t, err)
51+
52+
errs := ValidateInputPackagesPolicyTemplates(fspath.DirFS(d))
53+
require.NotEmpty(t, errs, "expected no validation errors")
54+
55+
assert.Len(t, errs, 1)
56+
assert.ErrorIs(t, errs[0], errRequiredTemplatePath)
57+
})
58+
59+
t.Run("policy_templates_missing_template_path", func(t *testing.T) {
60+
d := t.TempDir()
61+
62+
err := os.MkdirAll(filepath.Join(d, "agent", "input"), 0o755)
63+
require.NoError(t, err)
64+
err = os.WriteFile(filepath.Join(d, "manifest.yml"), []byte(`
65+
type: input
66+
policy_templates:
67+
- name: udp
68+
template_path: missing.yml.hbs
69+
`), 0o644)
70+
require.NoError(t, err)
71+
72+
errs := ValidateInputPackagesPolicyTemplates(fspath.DirFS(d))
73+
require.NotEmpty(t, errs, "expected validation errors")
74+
assert.Len(t, errs, 1)
75+
assert.ErrorIs(t, errs[0], errTemplateNotFound)
76+
})
77+
78+
t.Run("not_input_package_type", func(t *testing.T) {
79+
d := t.TempDir()
80+
81+
err := os.MkdirAll(filepath.Join(d, "agent", "input"), 0o755)
82+
require.NoError(t, err)
83+
err = os.WriteFile(filepath.Join(d, "manifest.yml"), []byte(`
84+
type: integration
85+
policy_templates:
86+
- name: udp
87+
template_path: missing.yml.hbs
88+
`), 0o644)
89+
require.NoError(t, err)
90+
91+
errs := ValidateInputPackagesPolicyTemplates(fspath.DirFS(d))
92+
require.NotEmpty(t, errs, "expected validation errors")
93+
assert.Len(t, errs, 1)
94+
assert.ErrorIs(t, errs[0], errInvalidPackageType)
95+
})
96+
97+
}

code/go/internal/validator/spec.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ func (s Spec) rules(pkgType string, rootSpec spectypes.ItemSpec) validationRules
217217
{fn: semantic.ValidateDocsStructure},
218218
{fn: semantic.ValidateDeploymentModes, types: []string{"integration"}},
219219
{fn: semantic.ValidateDurationVariables, since: semver.MustParse("3.5.0")},
220+
{fn: semantic.ValidateInputPackagesPolicyTemplates, types: []string{"input"}},
220221
{fn: semantic.ValidateMinimumAgentVersion},
221222
}
222223

code/go/pkg/validator/validator_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ func TestValidateFile(t *testing.T) {
310310
"field policy_templates.0.input: Must not be present",
311311
},
312312
},
313+
"bad_input_template_path": {
314+
"manifest.yml",
315+
[]string{
316+
"field policy_templates.0: template_path is required",
317+
"policy template \"sql_query\" references template_path \"\": template_path is required for input type packages",
318+
},
319+
},
313320
}
314321

315322
for pkgName, test := range tests {

spec/changelog.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
- description: Add support for script testing in data streams.
2424
type: enhancement
2525
link: https://github.com/elastic/package-spec/pull/985
26+
- description: Input packages require to define template_path in manifest.
27+
type: enhancement
28+
link: https://github.com/elastic/package-spec/pull/1000
2629
- description: Allow to define agent version constrains in input and integration packages.
2730
type: enhancement
2831
link: https://github.com/elastic/package-spec/pull/999

spec/input/manifest.spec.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ spec:
9494
- description
9595
- type
9696
- input
97+
- template_path
9798
icons:
9899
$ref: "../integration/manifest.spec.yml#/definitions/icons"
99100
screenshots:

test/packages/bad_duplicated_fields_input/manifest.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ policy_templates:
2727
type: logs
2828
input: log_file
2929
description: Collect sample logs
30+
template_path: input.yml.hbs
3031
vars:
3132
- name: paths
3233
required: true

0 commit comments

Comments
 (0)