@@ -391,6 +391,145 @@ jobs:
391391 find tests -type d -maxdepth 1 -mindepth 1 | sed 's|^tests/||g' | while read -r TESTSET; do echo "$TESTSET=true" >> "$GITHUB_OUTPUT"; echo "$TESTSET::true"; done
392392 find package/default/data -type d -name "spl2" -maxdepth 1 -mindepth 1 | sed 's|^package/default/data/||g' | while read -r TESTSET; do echo "$TESTSET=true" >> "$GITHUB_OUTPUT"; echo "$TESTSET::true"; done
393393
394+ run-escu-tests :
395+ if : ${{ !cancelled() && needs.setup-workflow.outputs.execute-escu-labeled == 'true' }}
396+ needs :
397+ - build
398+ - setup-workflow
399+ - setup
400+
401+ runs-on : ubuntu-latest
402+ strategy :
403+ fail-fast : false
404+ matrix :
405+ python-version :
406+ - " 3.11"
407+ permissions :
408+ actions : read
409+ deployments : read
410+ contents : read
411+ packages : read
412+ statuses : read
413+ checks : write
414+ steps :
415+ - uses : actions/checkout@v4
416+ - uses : actions/setup-python@v5
417+ with :
418+ python-version : ${{ matrix.python-version }}
419+
420+ - name : Install Python Dependencies and ContentCTL
421+ run : |
422+ pip install contentctl
423+ git clone https://github.com/splunk/security_content.git
424+
425+
426+ - name : Download TA Build Artifact
427+ uses : actions/download-artifact@v4
428+ with :
429+ name : package-splunkbase
430+ path : ta_build
431+
432+ - name : Get the build path
433+ run : |
434+ TA_BUILD=$(ls ta_build)
435+ TA_BUILD_PATH="${{ github.workspace }}/ta_build/$TA_BUILD"
436+ echo "TA_BUILD_PATH=$TA_BUILD_PATH" >> $GITHUB_ENV
437+
438+ - name : Run Python Script
439+ id : filter-detection-files
440+ shell : python
441+ run : |
442+ import yaml
443+ import os
444+ import configparser
445+ import re
446+
447+ GITHUB_REPOSITORY = os.environ.get("GITHUB_REPOSITORY", "")
448+
449+ # Parse app.conf get the appid of the TA.
450+ config = configparser.ConfigParser(strict=False)
451+ config.read("package/default/app.conf")
452+ APP_ID = config.get("id", "name")
453+ APP_LABEL = config.get("ui", "label")
454+
455+ # Read the file and remove trailing backslashes
456+ with open("package/default/props.conf", "r") as f:
457+ content = f.read()
458+
459+ # Remove trailing backslashes followed by a newline
460+ updated_content = re.sub(r"\\\n", "", content)
461+
462+ # Write the cleaned content to a new file
463+ with open("package/default/props.conf", "w") as f:
464+ f.write(updated_content)
465+
466+ # Parse props.conf and collect all the sourcetypes in a list.
467+ config = configparser.ConfigParser(strict=False)
468+ config.read("package/default/props.conf")
469+ sourcetypes = config.sections()
470+
471+ # Load the YAML content
472+ with open("security_content/contentctl.yml", "r") as file:
473+ data = yaml.safe_load(file)
474+
475+ found = False
476+
477+ for app in data["apps"]:
478+ if app['appid'] == APP_ID or GITHUB_REPOSITORY in app['hardcoded_path'] or app["title"] == APP_LABEL:
479+ app['hardcoded_path'] = "${{ env.TA_BUILD_PATH }}"
480+ found = True
481+ elif app['appid'] == "PALO_ALTO_NETWORKS_ADD_ON_FOR_SPLUNK" and APP_ID == "Splunk_TA_paloalto_networks":
482+ app['hardcoded_path'] = "${{ env.TA_BUILD_PATH }}"
483+ found = True
484+
485+ if not found:
486+ exit(127)
487+
488+
489+ # Write the modified data to the contentctl.yml file
490+ with open("security_content/contentctl.yml", "w") as file:
491+ yaml.dump(data,file,sort_keys=False)
492+
493+ # Filter out the detections based on the collected sourcetypes
494+ base_dir = "security_content/detections"
495+ detection_files = ""
496+
497+ for root, dirs, files in os.walk(base_dir):
498+ for file in files:
499+ file_path = os.path.join(root, file)
500+
501+ try:
502+ with open(file_path, "r") as file:
503+ file_content = yaml.safe_load(file)
504+ if "deprecated" not in file_path and (file_content["tests"][0]["attack_data"][0]["sourcetype"] in sourcetypes or file_content["tests"][0]["attack_data"][0]["source"] in sourcetypes):
505+ detection_files += file_path.replace("security_content/", "") + " "
506+
507+
508+ except Exception as e:
509+ continue
510+
511+ # Save detection_files as an output variable
512+ with open(os.getenv('GITHUB_OUTPUT'), 'w') as output_file:
513+ output_file.write(f"DETECTION_FILES={detection_files}")
514+
515+ print(f"Filtered Detection files = {detection_files}")
516+
517+ - name : Run ESCU Tests
518+ run : |
519+
520+ cd security_content
521+ echo "Content of contentctl.yml file"
522+ cat contentctl.yml
523+
524+ contentctl test --container-settings.num-containers 8 --post-test-behavior never_pause --disable-tqdm mode:selected --mode.files ${{ steps.filter-detection-files.outputs.DETECTION_FILES }}
525+
526+ - uses : actions/upload-artifact@v4
527+ if : always()
528+ with :
529+ name : escu_test_summary_results
530+ path : |
531+ security_content/test_results/summary.yml
532+
394533 run-unit-tests :
395534 name : test-unit-python3-${{ matrix.python-version }}
396535 if : ${{ needs.test-inventory.outputs.unit == 'true' }}
0 commit comments