-
Notifications
You must be signed in to change notification settings - Fork 129
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
inputsobject format in the Fleet API, default values for required variables are automatically added by the API service. However, elastic-package currently uses the deprecatedinputsarray 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 systemforbeyondtrust_praintegration with Kibana 9.2.0+. - Observe the API error when a non-required
urlvariable 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 (
inputsobject) 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 varsImpact
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