2020-06-29 23:19:23 -06:00
|
|
|
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
2021-03-03 22:12:11 -09:00
|
|
|
# or more contributor license agreements. Licensed under the Elastic License
|
|
|
|
|
# 2.0; you may not use this file except in compliance with the Elastic License
|
|
|
|
|
# 2.0.
|
2020-06-29 23:19:23 -06:00
|
|
|
|
|
|
|
|
"""Test that the packages are built correctly."""
|
2025-07-01 15:20:55 +02:00
|
|
|
|
2020-06-29 23:19:23 -06:00
|
|
|
import unittest
|
|
|
|
|
import uuid
|
2025-07-01 15:20:55 +02:00
|
|
|
|
2023-11-01 12:47:40 -04:00
|
|
|
from marshmallow import ValidationError
|
2025-07-01 15:20:55 +02:00
|
|
|
from semver import Version
|
2020-06-29 23:19:23 -06:00
|
|
|
|
|
|
|
|
from detection_rules import rule_loader
|
2020-09-30 17:43:45 -05:00
|
|
|
from detection_rules.packaging import PACKAGE_FILE, Package
|
2025-07-01 15:20:55 +02:00
|
|
|
from detection_rules.schemas.registry_package import RegistryPackageManifestV1, RegistryPackageManifestV3
|
2021-04-05 14:23:37 -06:00
|
|
|
from tests.base import BaseRuleTest
|
2020-06-29 23:19:23 -06:00
|
|
|
|
2021-03-09 13:30:12 -09:00
|
|
|
package_configs = Package.load_configs()
|
|
|
|
|
|
|
|
|
|
|
2021-04-05 14:23:37 -06:00
|
|
|
class TestPackages(BaseRuleTest):
|
2020-06-29 23:19:23 -06:00
|
|
|
"""Test package building and saving."""
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def get_test_rule(version=1, count=1):
|
|
|
|
|
def get_rule_contents():
|
2025-07-01 15:20:55 +02:00
|
|
|
return {
|
2020-06-29 23:19:23 -06:00
|
|
|
"author": ["Elastic"],
|
|
|
|
|
"description": "test description",
|
|
|
|
|
"language": "kuery",
|
2021-03-03 22:12:11 -09:00
|
|
|
"license": "Elastic License v2",
|
2020-06-29 23:19:23 -06:00
|
|
|
"name": "test rule",
|
|
|
|
|
"query": "process.name:test.query",
|
|
|
|
|
"risk_score": 21,
|
|
|
|
|
"rule_id": str(uuid.uuid4()),
|
|
|
|
|
"severity": "low",
|
2025-07-01 15:20:55 +02:00
|
|
|
"type": "query",
|
2020-06-29 23:19:23 -06:00
|
|
|
}
|
|
|
|
|
|
2025-07-01 15:20:55 +02:00
|
|
|
rules = [rule_loader.TOMLRule("test.toml", get_rule_contents()) for i in range(count)]
|
2020-06-29 23:19:23 -06:00
|
|
|
version_info = {
|
2025-07-01 15:20:55 +02:00
|
|
|
rule.id: {"rule_name": rule.name, "sha256": rule.contents.get_hash(), "version": version} for rule in rules
|
2020-06-29 23:19:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rules, version_info
|
|
|
|
|
|
|
|
|
|
def test_package_loader_production_config(self):
|
|
|
|
|
"""Test that packages are loading correctly."""
|
|
|
|
|
|
2025-07-01 15:20:55 +02:00
|
|
|
@unittest.skipIf(rule_loader.RULES_CONFIG.bypass_version_lock, "Version lock bypassed")
|
2020-06-29 23:19:23 -06:00
|
|
|
def test_package_loader_default_configs(self):
|
2024-05-15 15:18:39 -05:00
|
|
|
"""Test configs in detection_rules/etc/packages.yaml."""
|
2024-08-06 18:07:12 -04:00
|
|
|
Package.from_config(rule_collection=self.rc, config=package_configs)
|
2020-06-29 23:19:23 -06:00
|
|
|
|
2025-07-01 15:20:55 +02:00
|
|
|
@unittest.skipIf(rule_loader.RULES_CONFIG.bypass_version_lock, "Version lock bypassed")
|
2020-06-29 23:19:23 -06:00
|
|
|
def test_package_summary(self):
|
|
|
|
|
"""Test the generation of the package summary."""
|
2024-08-06 18:07:12 -04:00
|
|
|
rules = self.rc
|
2025-07-01 15:20:55 +02:00
|
|
|
package = Package(rules, "test-package")
|
2021-08-24 16:56:11 -06:00
|
|
|
package.generate_summary_and_changelog(package.changed_ids, package.new_ids, package.removed_ids)
|
2020-06-29 23:19:23 -06:00
|
|
|
|
2025-07-01 15:20:55 +02:00
|
|
|
@unittest.skipIf(rule_loader.RULES_CONFIG.bypass_version_lock, "Version lock bypassed")
|
2020-06-29 23:19:23 -06:00
|
|
|
def test_rule_versioning(self):
|
|
|
|
|
"""Test that all rules are properly versioned and tracked"""
|
|
|
|
|
self.maxDiff = None
|
2024-08-06 18:07:12 -04:00
|
|
|
rules = self.rc
|
2020-06-29 23:19:23 -06:00
|
|
|
original_hashes = []
|
|
|
|
|
|
|
|
|
|
# test that no rules have versions defined
|
|
|
|
|
for rule in rules:
|
2025-07-01 15:20:55 +02:00
|
|
|
self.assertGreaterEqual(rule.contents.autobumped_version, 1, "{} - {}: version is not being set in package")
|
2025-04-28 18:29:55 +02:00
|
|
|
original_hashes.append(rule.contents.get_hash())
|
2020-06-29 23:19:23 -06:00
|
|
|
|
2025-07-01 15:20:55 +02:00
|
|
|
package = Package(rules, "test-package")
|
2020-06-29 23:19:23 -06:00
|
|
|
|
|
|
|
|
# test that all rules have versions defined
|
|
|
|
|
for rule in package.rules:
|
2025-07-01 15:20:55 +02:00
|
|
|
self.assertGreaterEqual(rule.contents.autobumped_version, 1, "{} - {}: version is not being set in package")
|
2020-06-29 23:19:23 -06:00
|
|
|
|
|
|
|
|
# test that rules validate with version
|
2025-07-01 15:20:55 +02:00
|
|
|
|
|
|
|
|
post_bump_hashes = [rule.contents.get_hash() for rule in package.rules]
|
2020-06-29 23:19:23 -06:00
|
|
|
|
|
|
|
|
# test that no hashes changed as a result of the version bumps
|
2025-07-01 15:20:55 +02:00
|
|
|
self.assertListEqual(original_hashes, post_bump_hashes, "Version bumping modified the hash of a rule")
|
2020-06-29 23:19:23 -06:00
|
|
|
|
2021-03-09 13:30:12 -09:00
|
|
|
|
|
|
|
|
class TestRegistryPackage(unittest.TestCase):
|
|
|
|
|
"""Test the OOB registry package."""
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def setUpClass(cls) -> None:
|
2025-07-01 15:20:55 +02:00
|
|
|
assert "registry_data" in package_configs, f"Missing registry_data in {PACKAGE_FILE}"
|
|
|
|
|
cls.registry_config = package_configs["registry_data"]
|
|
|
|
|
stack_version = Version.parse(
|
|
|
|
|
cls.registry_config["conditions"]["kibana.version"].strip("^"), optional_minor_and_patch=True
|
|
|
|
|
)
|
2023-11-01 12:47:40 -04:00
|
|
|
if stack_version >= Version.parse("8.12.0"):
|
|
|
|
|
RegistryPackageManifestV3.from_dict(cls.registry_config)
|
|
|
|
|
else:
|
|
|
|
|
RegistryPackageManifestV1.from_dict(cls.registry_config)
|
2021-03-09 13:30:12 -09:00
|
|
|
|
|
|
|
|
def test_registry_package_config(self):
|
|
|
|
|
"""Test that the registry package is validating properly."""
|
|
|
|
|
registry_config = self.registry_config.copy()
|
2025-07-01 15:20:55 +02:00
|
|
|
registry_config["version"] += "7.1.1."
|
2021-03-09 13:30:12 -09:00
|
|
|
|
|
|
|
|
with self.assertRaises(ValidationError):
|
2023-11-01 12:47:40 -04:00
|
|
|
RegistryPackageManifestV1.from_dict(registry_config)
|