Skip to content

Commit e205165

Browse files
authored
Add conditions.agent.version into integration and input manifest spec with validation (#999)
Adds a new property into the integration and input spec to add the minimum agent version a package is compatible with. The new field is required after 3.6
1 parent 1c98376 commit e205165

File tree

130 files changed

+4836
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+4836
-1
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
11+
"github.com/Masterminds/semver/v3"
12+
13+
"github.com/elastic/package-spec/v3/code/go/internal/fspath"
14+
"github.com/elastic/package-spec/v3/code/go/internal/pkgpath"
15+
"github.com/elastic/package-spec/v3/code/go/pkg/specerrors"
16+
)
17+
18+
var (
19+
errInvalidAgentVersionCondition = fmt.Errorf("invalid agent.version condition")
20+
errAgentVersionIncorrectType = fmt.Errorf("manifest agent version is not a string")
21+
)
22+
23+
// ValidateMinimumAgentVersion checks that the package manifest includes the agent.version condition.
24+
func ValidateMinimumAgentVersion(fsys fspath.FS) specerrors.ValidationErrors {
25+
manifest, err := readManifest(fsys)
26+
if err != nil {
27+
return specerrors.ValidationErrors{specerrors.NewStructuredError(err, specerrors.UnassignedCode)}
28+
}
29+
30+
agentVersionCondition, err := getAgentVersionCondition(*manifest)
31+
if err != nil {
32+
return specerrors.ValidationErrors{specerrors.NewStructuredError(err, specerrors.UnassignedCode)}
33+
}
34+
35+
if agentVersionCondition != "" {
36+
if _, err := semver.NewConstraint(agentVersionCondition); err != nil {
37+
return specerrors.ValidationErrors{specerrors.NewStructuredError(errors.Join(err, errInvalidAgentVersionCondition), specerrors.UnassignedCode)}
38+
}
39+
}
40+
41+
return nil
42+
}
43+
44+
func getAgentVersionCondition(manifest pkgpath.File) (string, error) {
45+
val, err := manifest.Values("$.conditions[\"agent.version\"]")
46+
if err != nil {
47+
val, err = manifest.Values("$.conditions.agent.version")
48+
if err != nil {
49+
return "", nil
50+
}
51+
}
52+
53+
sVal, ok := val.(string)
54+
if !ok {
55+
return "", errAgentVersionIncorrectType
56+
}
57+
58+
return sVal, nil
59+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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/require"
13+
14+
"github.com/elastic/package-spec/v3/code/go/internal/fspath"
15+
)
16+
17+
func TestValidateMinimumAgentVersion(t *testing.T) {
18+
cases := []struct {
19+
title string
20+
manifestYAML string
21+
expectedErr error
22+
}{
23+
{
24+
title: "valid - agent.version condition is present",
25+
manifestYAML: `
26+
name: test-package
27+
version: 1.0.0
28+
conditions:
29+
agent:
30+
version: "^8.0.0"
31+
`,
32+
expectedErr: nil,
33+
},
34+
{
35+
title: "invalid - agent.version condition is missing",
36+
manifestYAML: `
37+
name: test-package
38+
version: 1.0.0
39+
conditions:
40+
some.other.condition: "value"
41+
`,
42+
expectedErr: nil,
43+
},
44+
{
45+
title: "invalid - agent.version condition is not a string",
46+
manifestYAML: `
47+
name: test-package
48+
version: 1.0.0
49+
conditions:
50+
agent.version:
51+
min: "^8.0.0"
52+
`,
53+
expectedErr: errAgentVersionIncorrectType,
54+
},
55+
{
56+
title: "invalid - agent.version condition is not a constraint",
57+
manifestYAML: `
58+
name: test-package
59+
version: 1.0.0
60+
conditions:
61+
agent.version: test
62+
`,
63+
expectedErr: errInvalidAgentVersionCondition,
64+
},
65+
}
66+
67+
for _, c := range cases {
68+
t.Run(c.title, func(t *testing.T) {
69+
tempDir := t.TempDir()
70+
71+
manifestPath := filepath.Join(tempDir, "manifest.yml")
72+
err := os.WriteFile(manifestPath, []byte(c.manifestYAML), 0644)
73+
require.NoError(t, err)
74+
75+
fsys := fspath.DirFS(tempDir)
76+
errs := ValidateMinimumAgentVersion(fsys)
77+
78+
if c.expectedErr != nil {
79+
require.Len(t, errs, 1)
80+
require.ErrorIs(t, errs[0], c.expectedErr)
81+
} else {
82+
require.Empty(t, errs)
83+
}
84+
})
85+
}
86+
87+
}

code/go/internal/validator/spec.go

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

223224
var validationRules validationRules

code/go/pkg/validator/validator_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,12 @@ func TestValidateFile(t *testing.T) {
317317
"policy template \"sql_query\" references template_path \"\": template_path is required for input type packages",
318318
},
319319
},
320+
"bad_agent_version_v3": {
321+
"manifest.yml",
322+
[]string{
323+
"field conditions.agent: version is required",
324+
},
325+
},
320326
}
321327

322328
for pkgName, test := range tests {

spec/changelog.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
- description: Add support for semantic_text field definition.
1313
type: enhancement
1414
link: https://github.com/elastic/package-spec/pull/807
15+
- description: Require defining agent version constraints in input and integration packages.
16+
type: breaking-change
17+
link: https://github.com/elastic/package-spec/pull/999
1518
- version: 3.5.1-next
1619
changes:
1720
- description: Input packages don't require to define fields.
@@ -23,6 +26,9 @@
2326
- description: Input packages require to define template_path in manifest.
2427
type: enhancement
2528
link: https://github.com/elastic/package-spec/pull/1000
29+
- description: Allow to define agent version constrains in input and integration packages.
30+
type: enhancement
31+
link: https://github.com/elastic/package-spec/pull/999
2632
- version: 3.5.0
2733
changes:
2834
- description: Add `duration` variable data type with `min_duration` and `max_duration` validation properties.

spec/content/manifest.spec.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ spec:
6666
categories:
6767
$ref: "../integration/manifest.spec.yml#/definitions/categories"
6868
conditions:
69-
$ref: "../integration/manifest.spec.yml#/definitions/conditions"
69+
description: Conditions under which this package can be installed.
70+
type: object
71+
additionalProperties: false
72+
properties:
73+
elastic:
74+
$ref: "../integration/manifest.spec.yml#/definitions/conditions/properties/elastic"
75+
kibana:
76+
$ref: "../integration/manifest.spec.yml#/definitions/conditions/properties/kibana"
7077
discovery:
7178
$ref: "#/definitions/discovery"
7279
icons:

spec/input/manifest.spec.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,14 @@ spec:
120120
- version
121121
- type
122122
- owner
123+
- conditions
123124

124125
# JSON patches for newer versions should be placed on top
125126
versions:
127+
- before: 3.6.0
128+
patch:
129+
- op: remove
130+
path: "/required/7" # removes requirement for conditions
126131
# Reserve otelcol input name before 3.5.0.
127132
- before: 3.5.0
128133
patch:

spec/integration/manifest.spec.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,20 @@ spec:
217217
description: Kibana versions compatible with this package.
218218
examples:
219219
- ">=7.9.0"
220+
agent:
221+
description: Elastic Agent conditions
222+
type: object
223+
additionalProperties: false
224+
properties:
225+
version:
226+
type: string
227+
description: Elastic Agent versions compatible with this package.
228+
examples:
229+
- "^9.5.0"
230+
required:
231+
- version
232+
required:
233+
- agent
220234
description:
221235
description: >
222236
A longer description of the package. It should describe, at least all the kinds of
@@ -670,6 +684,7 @@ spec:
670684
- version
671685
- type
672686
- owner
687+
- conditions
673688
allOf:
674689
- if:
675690
properties:
@@ -692,6 +707,14 @@ spec:
692707

693708
# JSON patches for newer versions should be placed on top
694709
versions:
710+
- before: 3.6.0
711+
patch:
712+
- op: remove
713+
path: "/required/7" # removes requirement for conditions
714+
- op: remove
715+
path: "/definitions/conditions/required/0" # removes requirement for agent
716+
- op: remove
717+
path: "/definitions/conditions/properties/agent/required/0" # removes requirement for version
695718
- before: 3.3.2
696719
patch:
697720
- op: remove

0 commit comments

Comments
 (0)