-
Notifications
You must be signed in to change notification settings - Fork 127
Description
Summary
When testing the beyondtrust_pra
integration in the elastic/integrations
repo after Kibana 9.2.0 introduced URL validation for the url
variable type, I encountered errors when running system tests with elastic-package
. The error occurs because elastic-package
sends null
for variables without a default and are not set in the test policy, specifically for variables of type url
. The same will also be true for the duration
variable which has min_duration and max_duration validations, but it is not currently used in any packages.
Example error:
system test: common in beyondtrust_pra.access_session
could not add data stream config to policy: could not add package to policy; API status code = 400; response body = {"statusCode":400,"error":"Bad Request","message":"Package policy is invalid: inputs.cel.vars.proxy_url: [\"Invalid URL format\"]"}
Request body sent:
{
"vars": {
"proxy_url": {
"value": null,
"type": "url"
},
...
}
}
Fleet's validation considers a variable as "defined" once it appears in the request, even if its value is null
. All defined variables undergo type validation, and null
fails URL validation. This results in errors for non-required url
variables that are unset.
Expected behavior
Variables without a default should be omitted from the API request if they are not set, rather than being included with a null
value. This will prevent unnecessary validation errors for unset, non-required variables of type url
.
Additional observations
- When using the newer
inputs
object format in the Fleet API, default values for required variables are automatically added by the API service. However, elastic-package currently uses the deprecatedinputs
array format, which requires all default values to be included explicitly in the request. - If default values are omitted, the API rejects the request, even for required variables with defaults specified in the manifest.
- Relevant code: elastic-package test runner source and Fleet validation logic.
Steps to reproduce
- Run
elastic-package test system
forbeyondtrust_pra
integration with Kibana 9.2.0+. - Observe the API error when a non-required
url
variable is not set in the test policy.
Suggested fix
- Update elastic-package to omit unset variables that do not have a default from the package policy request body.
- Consider switching to the supported Fleet API request format (
inputs
object) to benefit from automatic default value inclusion which would simplify building the package policy request.
Patch
diff --git a/internal/packages/archetype/data_stream_inputs.go b/internal/packages/archetype/data_stream_inputs.go
index cbbdd884..848043e3 100644
--- a/internal/packages/archetype/data_stream_inputs.go
+++ b/internal/packages/archetype/data_stream_inputs.go
@@ -84,6 +84,7 @@ func unpackVars(output *[]packages.Variable, input []InputVariable) {
newVar.MaxDuration = inputVar.MaxDuration
newVar.Description = inputVar.Description
if inputVar.Default != nil {
+ newVar.Default = &packages.VarValue{}
newVar.Default.Unpack(inputVar.Default)
}
*output = append(*output, newVar)
diff --git a/internal/packages/packages.go b/internal/packages/packages.go
index 3d4e60e2..218a7ac5 100644
--- a/internal/packages/packages.go
+++ b/internal/packages/packages.go
@@ -102,19 +102,19 @@ func VarValueYamlString(vv VarValue, field string, numSpaces ...int) string {
// Variable is an instance of configuration variable (named, typed).
type Variable struct {
- Name string `config:"name" json:"name" yaml:"name"`
- Type string `config:"type" json:"type" yaml:"type"`
- Title string `config:"title" json:"title" yaml:"title"`
- Description string `config:"description" json:"description" yaml:"description"`
- Multi bool `config:"multi" json:"multi" yaml:"multi"`
- Required bool `config:"required" json:"required" yaml:"required"`
- Secret bool `config:"secret" json:"secret" yaml:"secret"`
- ShowUser bool `config:"show_user" json:"show_user" yaml:"show_user"`
- HideInDeploymentModes []string `config:"hide_in_deployment_modes" json:"hide_in_deployment_modes" yaml:"hide_in_deployment_modes"`
- UrlAllowedSchemes []string `config:"url_allowed_schemes" json:"url_allowed_schemes" yaml:"url_allowed_schemes"`
- MinDuration string `config:"min_duration" json:"min_duration" yaml:"min_duration"`
- MaxDuration string `config:"max_duration" json:"max_duration" yaml:"max_duration"`
- Default VarValue `config:"default" json:"default" yaml:"default"`
+ Name string `config:"name" json:"name" yaml:"name"`
+ Type string `config:"type" json:"type" yaml:"type"`
+ Title string `config:"title" json:"title" yaml:"title"`
+ Description string `config:"description" json:"description" yaml:"description"`
+ Multi bool `config:"multi" json:"multi" yaml:"multi"`
+ Required bool `config:"required" json:"required" yaml:"required"`
+ Secret bool `config:"secret" json:"secret" yaml:"secret"`
+ ShowUser bool `config:"show_user" json:"show_user" yaml:"show_user"`
+ HideInDeploymentModes []string `config:"hide_in_deployment_modes" json:"hide_in_deployment_modes" yaml:"hide_in_deployment_modes"`
+ UrlAllowedSchemes []string `config:"url_allowed_schemes" json:"url_allowed_schemes" yaml:"url_allowed_schemes"`
+ MinDuration string `config:"min_duration" json:"min_duration" yaml:"min_duration"`
+ MaxDuration string `config:"max_duration" json:"max_duration" yaml:"max_duration"`
+ Default *VarValue `config:"default" json:"default" yaml:"default"`
}
// Input is a single input configuration.
diff --git a/internal/resources/fleetpolicy.go b/internal/resources/fleetpolicy.go
index 37b4e919..61ca1677 100644
--- a/internal/resources/fleetpolicy.go
+++ b/internal/resources/fleetpolicy.go
@@ -312,17 +312,24 @@ func createInputPackagePolicy(policy FleetAgentPolicy, manifest packages.Package
func setKibanaVariables(definitions []packages.Variable, values common.MapStr) kibana.Vars {
vars := kibana.Vars{}
for _, definition := range definitions {
+ // Elastic Package uses the deprecated 'inputs' array in its /api/fleet/package_policies request.
+ // When using this API parameter, default values are not automatically incorporated into
+ // the policy, whereas with the 'inputs' object, defaults are incorporated by the API service.
+ // This means that our client must include the default values in its request to ensure correct behavior.
val := definition.Default
value, err := values.GetValue(definition.Name)
if err == nil {
- val = packages.VarValue{}
+ val = &packages.VarValue{}
val.Unpack(value)
+ } else if errors.Is(err, common.ErrKeyNotFound) && definition.Default == nil {
+ // Do not include nulls for unset variables.
+ continue
}
vars[definition.Name] = kibana.Var{
Type: definition.Type,
- Value: val,
+ Value: *val,
}
}
return vars
diff --git a/internal/testrunner/runners/system/tester.go b/internal/testrunner/runners/system/tester.go
index 362cb486..21517acd 100644
--- a/internal/testrunner/runners/system/tester.go
+++ b/internal/testrunner/runners/system/tester.go
@@ -2042,17 +2042,24 @@ func createInputPackageDatastream(
func setKibanaVariables(definitions []packages.Variable, values common.MapStr) kibana.Vars {
vars := kibana.Vars{}
for _, definition := range definitions {
+ // Elastic Package uses the deprecated 'inputs' array in its /api/fleet/package_policies request.
+ // When using this API parameter, default values are not automatically incorporated into
+ // the policy, whereas with the 'inputs' object, defaults are incorporated by the API service.
+ // This means that our client must include the default values in its request to ensure correct behavior.
val := definition.Default
value, err := values.GetValue(definition.Name)
if err == nil {
- val = packages.VarValue{}
+ val = &packages.VarValue{}
val.Unpack(value)
+ } else if errors.Is(err, common.ErrKeyNotFound) && definition.Default == nil {
+ // Do not include nulls for unset variables.
+ continue
}
vars[definition.Name] = kibana.Var{
Type: definition.Type,
- Value: val,
+ Value: *val,
}
}
return vars
Impact
This bug prevents system tests from passing due to invalid API requests, particularly for integrations using non-required variables of type url
. This affects:
- beyondtrust_pra.access_session
- ti_cif3.feed
- ti_recordedfuture.threat