From 119c98f05f87725be5097df91a7aa81956d8eaff Mon Sep 17 00:00:00 2001 From: Justin Ibarra Date: Wed, 8 Jul 2020 18:58:00 -0500 Subject: [PATCH] Package kibana index file with release rules (#40) --- detection_rules/main.py | 11 ++--------- detection_rules/misc.py | 14 ++++++++++++++ detection_rules/packaging.py | 29 ++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/detection_rules/main.py b/detection_rules/main.py index d2f3c4df7a6..7246768225c 100644 --- a/detection_rules/main.py +++ b/detection_rules/main.py @@ -13,7 +13,7 @@ import pytoml from eql import load_dump -from .misc import nested_set +from .misc import PYTHON_LICENSE, nested_set from . import rule_loader from .packaging import PACKAGE_FILE, Package, manage_versions from .rule import RULE_TYPE_OPTIONS, Rule @@ -157,13 +157,6 @@ def validate_rule(rule_id, rule_name, path): return rule -license_header = """ -# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -# or more contributor license agreements. Licensed under the Elastic License; -# you may not use this file except in compliance with the Elastic License. -""".strip() - - @root.command('license-check') @click.pass_context def license_check(ctx): @@ -184,7 +177,7 @@ def license_check(ctx): if contents.startswith("#!/"): _, _, contents = contents.partition("\n") - if not contents.lstrip("\r\n").startswith(license_header): + if not contents.lstrip("\r\n").startswith(PYTHON_LICENSE): if not failed: click.echo("Missing license headers for:", err=True) diff --git a/detection_rules/misc.py b/detection_rules/misc.py index 694b60518d7..9cbb7bcd05a 100644 --- a/detection_rules/misc.py +++ b/detection_rules/misc.py @@ -16,6 +16,20 @@ _CONFIG = {} +LICENSE_HEADER = """ +Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +or more contributor license agreements. Licensed under the Elastic License; +you may not use this file except in compliance with the Elastic License. +""".strip() + +LICENSE_LINES = LICENSE_HEADER.splitlines() +PYTHON_LICENSE = "\n".join("# " + line for line in LICENSE_LINES) +JS_LICENSE = """ +/* +{} + */ +""".strip().format("\n".join(' * ' + line for line in LICENSE_LINES)) + def nested_get(_dict, dot_key, default=None): """Get a nested field from a nested dict with dot notation.""" diff --git a/detection_rules/packaging.py b/detection_rules/packaging.py index 064f1b66439..d7b622d0b9e 100644 --- a/detection_rules/packaging.py +++ b/detection_rules/packaging.py @@ -13,6 +13,7 @@ import click from . import rule_loader +from .misc import JS_LICENSE from .rule import Rule # noqa: F401 from .utils import get_path, get_etc_path @@ -129,12 +130,37 @@ def _package_notice_file(save_dir): with open(NOTICE_FILE, 'rt') as f: notice_txt = f.read() - with open(os.path.join(save_dir, 'notice.ts'), 'w') as f: + with open(os.path.join(save_dir, 'notice.ts'), 'wt') as f: commented_notice = [' * ' + line for line in notice_txt.splitlines()] lines = ['/* eslint-disable @kbn/eslint/require-license-header */', '', '/* @notice'] lines = lines + commented_notice + [' */', ''] f.write('\n'.join(lines)) + def _package_index_file(self, save_dir): + """Convert and save index file with package.""" + sorted_rules = sorted(self.rules, key=lambda k: (k.metadata['creation_date'], os.path.basename(k.path))) + comments = [ + '// Auto generated file from either:', + '// - scripts/regen_prepackage_rules_index.sh', + '// - detection-rules repo using CLI command build-release', + '// Do not hand edit. Run script/command to regenerate package information instead', + ] + rule_imports = [f"import rule{i} from './{os.path.splitext(os.path.basename(r.path))[0] + '.json'}';" + for i, r in enumerate(sorted_rules, 1)] + const_exports = ['export const rawRules = ['] + const_exports.extend(f" rule{i}," for i, _ in enumerate(sorted_rules, 1)) + const_exports.append("];") + const_exports.append(" ") + + index_ts = [JS_LICENSE, ""] + index_ts.extend(comments) + index_ts.append("") + index_ts.extend(rule_imports) + index_ts.append("") + index_ts.extend(const_exports) + with open(os.path.join(save_dir, 'index.ts'), 'wt') as f: + f.write('\n'.join(index_ts)) + def save_release_files(self, directory, changed_rules, new_rules): """Release a package.""" with open(os.path.join(directory, '{}-summary.txt'.format(self.name)), 'w') as f: @@ -165,6 +191,7 @@ def save(self, verbose=True): rule.save(new_path=os.path.join(rules_dir, os.path.basename(rule.path))) self._package_notice_file(rules_dir) + self._package_index_file(rules_dir) if self.release: self.save_release_files(extras_dir, self.changed_rules, self.new_rules)