We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
FileNotFoundError after version 3.8.1
### Discussed in https://github.com/prowler-cloud/prowler/discussions/2707

<div type='discussions-op-text'>

<sup>Originally posted by **cerontrustly** August 10, 2023</sup>
Hello guys!

After using version 3.8.1 Prowler stopped working for me showing the following error:

`Traceback (most recent call last):
  File "/home/prowler/.local/bin/prowler", line 8, in <module>
    sys.exit(prowler())
  File "/home/prowler/.local/lib/python3.9/site-packages/prowler/__main__.py", line 222, in prowler
    resolve_security_hub_previous_findings(
  File "/home/prowler/.local/lib/python3.9/site-packages/prowler/providers/aws/lib/security_hub/security_hub.py", line 66, in resolve_security_hub_previous_findings
    with open(f"{output_directory}/{output_filename}{json_asff_file_suffix}") as f:
FileNotFoundError: [Errno 2] No such file or directory: '/home/prowler/output/None.asff.json'`

My command line looks like this:

`docker run -v /tmp:/prowler/tmp toniblyx/prowler:stable -f us-west-2 -M json-asff -S -z`

I think it can be related to [this](https://github.com/prowler-cloud/prowler/pull/2687) change.

Can somebody you help me?

Thank you!</div>

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `prowler/__main__.py`
Content:
```
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 import os
5 import sys
6 
7 from prowler.lib.banner import print_banner
8 from prowler.lib.check.check import (
9     bulk_load_checks_metadata,
10     bulk_load_compliance_frameworks,
11     exclude_checks_to_run,
12     exclude_services_to_run,
13     execute_checks,
14     list_categories,
15     list_services,
16     parse_checks_from_folder,
17     print_categories,
18     print_checks,
19     print_compliance_frameworks,
20     print_compliance_requirements,
21     print_services,
22     remove_custom_checks_module,
23 )
24 from prowler.lib.check.checks_loader import load_checks_to_execute
25 from prowler.lib.check.compliance import update_checks_metadata_with_compliance
26 from prowler.lib.cli.parser import ProwlerArgumentParser
27 from prowler.lib.logger import logger, set_logging_config
28 from prowler.lib.outputs.compliance import display_compliance_table
29 from prowler.lib.outputs.html import add_html_footer, fill_html_overview_statistics
30 from prowler.lib.outputs.json import close_json
31 from prowler.lib.outputs.outputs import extract_findings_statistics, send_to_s3_bucket
32 from prowler.lib.outputs.slack import send_slack_message
33 from prowler.lib.outputs.summary_table import display_summary_table
34 from prowler.providers.aws.lib.security_hub.security_hub import (
35     resolve_security_hub_previous_findings,
36 )
37 from prowler.providers.common.allowlist import set_provider_allowlist
38 from prowler.providers.common.audit_info import (
39     set_provider_audit_info,
40     set_provider_execution_parameters,
41 )
42 from prowler.providers.common.outputs import set_provider_output_options
43 from prowler.providers.common.quick_inventory import run_provider_quick_inventory
44 
45 
46 def prowler():
47     # Parse Arguments
48     parser = ProwlerArgumentParser()
49     args = parser.parse()
50 
51     # Save Arguments
52     provider = args.provider
53     checks = args.checks
54     excluded_checks = args.excluded_checks
55     excluded_services = args.excluded_services
56     services = args.services
57     categories = args.categories
58     checks_file = args.checks_file
59     checks_folder = args.checks_folder
60     severities = args.severity
61     compliance_framework = args.compliance
62 
63     if not args.no_banner:
64         print_banner(args)
65 
66     # We treat the compliance framework as another output format
67     if compliance_framework:
68         args.output_modes.extend(compliance_framework)
69 
70     # Set Logger configuration
71     set_logging_config(args.log_level, args.log_file, args.only_logs)
72 
73     if args.list_services:
74         print_services(list_services(provider))
75         sys.exit()
76 
77     # Load checks metadata
78     logger.debug("Loading checks metadata from .metadata.json files")
79     bulk_checks_metadata = bulk_load_checks_metadata(provider)
80 
81     if args.list_categories:
82         print_categories(list_categories(bulk_checks_metadata))
83         sys.exit()
84 
85     bulk_compliance_frameworks = {}
86     # Load compliance frameworks
87     logger.debug("Loading compliance frameworks from .json files")
88 
89     bulk_compliance_frameworks = bulk_load_compliance_frameworks(provider)
90     # Complete checks metadata with the compliance framework specification
91     update_checks_metadata_with_compliance(
92         bulk_compliance_frameworks, bulk_checks_metadata
93     )
94     if args.list_compliance:
95         print_compliance_frameworks(bulk_compliance_frameworks)
96         sys.exit()
97     if args.list_compliance_requirements:
98         print_compliance_requirements(
99             bulk_compliance_frameworks, args.list_compliance_requirements
100         )
101         sys.exit()
102 
103     # Load checks to execute
104     checks_to_execute = load_checks_to_execute(
105         bulk_checks_metadata,
106         bulk_compliance_frameworks,
107         checks_file,
108         checks,
109         services,
110         severities,
111         compliance_framework,
112         categories,
113         provider,
114     )
115 
116     # If -l/--list-checks passed as argument, print checks to execute and quit
117     if args.list_checks:
118         print_checks(provider, sorted(checks_to_execute), bulk_checks_metadata)
119         sys.exit()
120 
121     # Set the audit info based on the selected provider
122     audit_info = set_provider_audit_info(provider, args.__dict__)
123 
124     # Import custom checks from folder
125     if checks_folder:
126         parse_checks_from_folder(audit_info, checks_folder, provider)
127 
128     # Exclude checks if -e/--excluded-checks
129     if excluded_checks:
130         checks_to_execute = exclude_checks_to_run(checks_to_execute, excluded_checks)
131 
132     # Exclude services if --excluded-services
133     if excluded_services:
134         checks_to_execute = exclude_services_to_run(
135             checks_to_execute, excluded_services, provider
136         )
137 
138     # Once the audit_info is set and we have the eventual checks based on the resource identifier,
139     # it is time to check what Prowler's checks are going to be executed
140     if audit_info.audit_resources:
141         checks_to_execute = set_provider_execution_parameters(provider, audit_info)
142 
143     # Sort final check list
144     checks_to_execute = sorted(checks_to_execute)
145 
146     # Parse Allowlist
147     allowlist_file = set_provider_allowlist(provider, audit_info, args)
148 
149     # Set output options based on the selected provider
150     audit_output_options = set_provider_output_options(
151         provider, args, audit_info, allowlist_file, bulk_checks_metadata
152     )
153 
154     # Run the quick inventory for the provider if available
155     if hasattr(args, "quick_inventory") and args.quick_inventory:
156         run_provider_quick_inventory(provider, audit_info, args)
157         sys.exit()
158 
159     # Execute checks
160     findings = []
161     if len(checks_to_execute):
162         findings = execute_checks(
163             checks_to_execute, provider, audit_info, audit_output_options
164         )
165     else:
166         logger.error(
167             "There are no checks to execute. Please, check your input arguments"
168         )
169 
170     # Extract findings stats
171     stats = extract_findings_statistics(findings)
172 
173     if args.slack:
174         if "SLACK_API_TOKEN" in os.environ and "SLACK_CHANNEL_ID" in os.environ:
175             _ = send_slack_message(
176                 os.environ["SLACK_API_TOKEN"],
177                 os.environ["SLACK_CHANNEL_ID"],
178                 stats,
179                 provider,
180                 audit_info,
181             )
182         else:
183             logger.critical(
184                 "Slack integration needs SLACK_API_TOKEN and SLACK_CHANNEL_ID environment variables (see more in https://docs.prowler.cloud/en/latest/tutorials/integrations/#slack)."
185             )
186             sys.exit(1)
187 
188     if args.output_modes:
189         for mode in args.output_modes:
190             # Close json file if exists
191             if "json" in mode:
192                 close_json(
193                     audit_output_options.output_filename, args.output_directory, mode
194                 )
195             if mode == "html":
196                 add_html_footer(
197                     audit_output_options.output_filename, args.output_directory
198                 )
199                 fill_html_overview_statistics(
200                     stats, audit_output_options.output_filename, args.output_directory
201                 )
202             # Send output to S3 if needed (-B / -D)
203             if provider == "aws" and (
204                 args.output_bucket or args.output_bucket_no_assume
205             ):
206                 output_bucket = args.output_bucket
207                 bucket_session = audit_info.audit_session
208                 # Check if -D was input
209                 if args.output_bucket_no_assume:
210                     output_bucket = args.output_bucket_no_assume
211                     bucket_session = audit_info.original_session
212                 send_to_s3_bucket(
213                     audit_output_options.output_filename,
214                     args.output_directory,
215                     mode,
216                     output_bucket,
217                     bucket_session,
218                 )
219 
220     # Resolve previous fails of Security Hub
221     if provider == "aws" and args.security_hub and not args.skip_sh_update:
222         resolve_security_hub_previous_findings(
223             args.output_directory, args.output_filename, audit_info
224         )
225 
226     # Display summary table
227     if not args.only_logs:
228         display_summary_table(
229             findings,
230             audit_info,
231             audit_output_options,
232             provider,
233         )
234 
235         if compliance_framework and findings:
236             for compliance in compliance_framework:
237                 # Display compliance table
238                 display_compliance_table(
239                     findings,
240                     bulk_checks_metadata,
241                     compliance,
242                     audit_output_options.output_filename,
243                     audit_output_options.output_directory,
244                 )
245 
246     # If custom checks were passed, remove the modules
247     if checks_folder:
248         remove_custom_checks_module(checks_folder, provider)
249 
250     # If there are failed findings exit code 3, except if -z is input
251     if not args.ignore_exit_code_3 and stats["total_fail"] > 0:
252         sys.exit(3)
253 
254 
255 if __name__ == "__main__":
256     prowler()
257
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/prowler/__main__.py b/prowler/__main__.py
--- a/prowler/__main__.py
+++ b/prowler/__main__.py
@@ -220,7 +220,9 @@
     # Resolve previous fails of Security Hub
     if provider == "aws" and args.security_hub and not args.skip_sh_update:
         resolve_security_hub_previous_findings(
-            args.output_directory, args.output_filename, audit_info
+            audit_output_options.output_directory,
+            audit_output_options.output_filename,
+            audit_info,
         )
 
     # Display summary table

{"golden_diff": "diff --git a/prowler/__main__.py b/prowler/__main__.py\n--- a/prowler/__main__.py\n+++ b/prowler/__main__.py\n@@ -220,7 +220,9 @@\n     # Resolve previous fails of Security Hub\n     if provider == \"aws\" and args.security_hub and not args.skip_sh_update:\n         resolve_security_hub_previous_findings(\n-            args.output_directory, args.output_filename, audit_info\n+            audit_output_options.output_directory,\n+            audit_output_options.output_filename,\n+            audit_info,\n         )\n \n     # Display summary table\n", "issue": "FileNotFoundError after version 3.8.1\n### Discussed in https://github.com/prowler-cloud/prowler/discussions/2707\r\n\r\n<div type='discussions-op-text'>\r\n\r\n<sup>Originally posted by **cerontrustly** August 10, 2023</sup>\r\nHello guys!\r\n\r\nAfter using version 3.8.1 Prowler stopped working for me showing the following error:\r\n\r\n`Traceback (most recent call last):\r\n  File \"/home/prowler/.local/bin/prowler\", line 8, in <module>\r\n    sys.exit(prowler())\r\n  File \"/home/prowler/.local/lib/python3.9/site-packages/prowler/__main__.py\", line 222, in prowler\r\n    resolve_security_hub_previous_findings(\r\n  File \"/home/prowler/.local/lib/python3.9/site-packages/prowler/providers/aws/lib/security_hub/security_hub.py\", line 66, in resolve_security_hub_previous_findings\r\n    with open(f\"{output_directory}/{output_filename}{json_asff_file_suffix}\") as f:\r\nFileNotFoundError: [Errno 2] No such file or directory: '/home/prowler/output/None.asff.json'`\r\n\r\nMy command line looks like this:\r\n\r\n`docker run -v /tmp:/prowler/tmp toniblyx/prowler:stable -f us-west-2 -M json-asff -S -z`\r\n\r\nI think it can be related to [this](https://github.com/prowler-cloud/prowler/pull/2687) change.\r\n\r\nCan somebody you help me?\r\n\r\nThank you!</div>\n", "before_files": [{"content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport os\nimport sys\n\nfrom prowler.lib.banner import print_banner\nfrom prowler.lib.check.check import (\n    bulk_load_checks_metadata,\n    bulk_load_compliance_frameworks,\n    exclude_checks_to_run,\n    exclude_services_to_run,\n    execute_checks,\n    list_categories,\n    list_services,\n    parse_checks_from_folder,\n    print_categories,\n    print_checks,\n    print_compliance_frameworks,\n    print_compliance_requirements,\n    print_services,\n    remove_custom_checks_module,\n)\nfrom prowler.lib.check.checks_loader import load_checks_to_execute\nfrom prowler.lib.check.compliance import update_checks_metadata_with_compliance\nfrom prowler.lib.cli.parser import ProwlerArgumentParser\nfrom prowler.lib.logger import logger, set_logging_config\nfrom prowler.lib.outputs.compliance import display_compliance_table\nfrom prowler.lib.outputs.html import add_html_footer, fill_html_overview_statistics\nfrom prowler.lib.outputs.json import close_json\nfrom prowler.lib.outputs.outputs import extract_findings_statistics, send_to_s3_bucket\nfrom prowler.lib.outputs.slack import send_slack_message\nfrom prowler.lib.outputs.summary_table import display_summary_table\nfrom prowler.providers.aws.lib.security_hub.security_hub import (\n    resolve_security_hub_previous_findings,\n)\nfrom prowler.providers.common.allowlist import set_provider_allowlist\nfrom prowler.providers.common.audit_info import (\n    set_provider_audit_info,\n    set_provider_execution_parameters,\n)\nfrom prowler.providers.common.outputs import set_provider_output_options\nfrom prowler.providers.common.quick_inventory import run_provider_quick_inventory\n\n\ndef prowler():\n    # Parse Arguments\n    parser = ProwlerArgumentParser()\n    args = parser.parse()\n\n    # Save Arguments\n    provider = args.provider\n    checks = args.checks\n    excluded_checks = args.excluded_checks\n    excluded_services = args.excluded_services\n    services = args.services\n    categories = args.categories\n    checks_file = args.checks_file\n    checks_folder = args.checks_folder\n    severities = args.severity\n    compliance_framework = args.compliance\n\n    if not args.no_banner:\n        print_banner(args)\n\n    # We treat the compliance framework as another output format\n    if compliance_framework:\n        args.output_modes.extend(compliance_framework)\n\n    # Set Logger configuration\n    set_logging_config(args.log_level, args.log_file, args.only_logs)\n\n    if args.list_services:\n        print_services(list_services(provider))\n        sys.exit()\n\n    # Load checks metadata\n    logger.debug(\"Loading checks metadata from .metadata.json files\")\n    bulk_checks_metadata = bulk_load_checks_metadata(provider)\n\n    if args.list_categories:\n        print_categories(list_categories(bulk_checks_metadata))\n        sys.exit()\n\n    bulk_compliance_frameworks = {}\n    # Load compliance frameworks\n    logger.debug(\"Loading compliance frameworks from .json files\")\n\n    bulk_compliance_frameworks = bulk_load_compliance_frameworks(provider)\n    # Complete checks metadata with the compliance framework specification\n    update_checks_metadata_with_compliance(\n        bulk_compliance_frameworks, bulk_checks_metadata\n    )\n    if args.list_compliance:\n        print_compliance_frameworks(bulk_compliance_frameworks)\n        sys.exit()\n    if args.list_compliance_requirements:\n        print_compliance_requirements(\n            bulk_compliance_frameworks, args.list_compliance_requirements\n        )\n        sys.exit()\n\n    # Load checks to execute\n    checks_to_execute = load_checks_to_execute(\n        bulk_checks_metadata,\n        bulk_compliance_frameworks,\n        checks_file,\n        checks,\n        services,\n        severities,\n        compliance_framework,\n        categories,\n        provider,\n    )\n\n    # If -l/--list-checks passed as argument, print checks to execute and quit\n    if args.list_checks:\n        print_checks(provider, sorted(checks_to_execute), bulk_checks_metadata)\n        sys.exit()\n\n    # Set the audit info based on the selected provider\n    audit_info = set_provider_audit_info(provider, args.__dict__)\n\n    # Import custom checks from folder\n    if checks_folder:\n        parse_checks_from_folder(audit_info, checks_folder, provider)\n\n    # Exclude checks if -e/--excluded-checks\n    if excluded_checks:\n        checks_to_execute = exclude_checks_to_run(checks_to_execute, excluded_checks)\n\n    # Exclude services if --excluded-services\n    if excluded_services:\n        checks_to_execute = exclude_services_to_run(\n            checks_to_execute, excluded_services, provider\n        )\n\n    # Once the audit_info is set and we have the eventual checks based on the resource identifier,\n    # it is time to check what Prowler's checks are going to be executed\n    if audit_info.audit_resources:\n        checks_to_execute = set_provider_execution_parameters(provider, audit_info)\n\n    # Sort final check list\n    checks_to_execute = sorted(checks_to_execute)\n\n    # Parse Allowlist\n    allowlist_file = set_provider_allowlist(provider, audit_info, args)\n\n    # Set output options based on the selected provider\n    audit_output_options = set_provider_output_options(\n        provider, args, audit_info, allowlist_file, bulk_checks_metadata\n    )\n\n    # Run the quick inventory for the provider if available\n    if hasattr(args, \"quick_inventory\") and args.quick_inventory:\n        run_provider_quick_inventory(provider, audit_info, args)\n        sys.exit()\n\n    # Execute checks\n    findings = []\n    if len(checks_to_execute):\n        findings = execute_checks(\n            checks_to_execute, provider, audit_info, audit_output_options\n        )\n    else:\n        logger.error(\n            \"There are no checks to execute. Please, check your input arguments\"\n        )\n\n    # Extract findings stats\n    stats = extract_findings_statistics(findings)\n\n    if args.slack:\n        if \"SLACK_API_TOKEN\" in os.environ and \"SLACK_CHANNEL_ID\" in os.environ:\n            _ = send_slack_message(\n                os.environ[\"SLACK_API_TOKEN\"],\n                os.environ[\"SLACK_CHANNEL_ID\"],\n                stats,\n                provider,\n                audit_info,\n            )\n        else:\n            logger.critical(\n                \"Slack integration needs SLACK_API_TOKEN and SLACK_CHANNEL_ID environment variables (see more in https://docs.prowler.cloud/en/latest/tutorials/integrations/#slack).\"\n            )\n            sys.exit(1)\n\n    if args.output_modes:\n        for mode in args.output_modes:\n            # Close json file if exists\n            if \"json\" in mode:\n                close_json(\n                    audit_output_options.output_filename, args.output_directory, mode\n                )\n            if mode == \"html\":\n                add_html_footer(\n                    audit_output_options.output_filename, args.output_directory\n                )\n                fill_html_overview_statistics(\n                    stats, audit_output_options.output_filename, args.output_directory\n                )\n            # Send output to S3 if needed (-B / -D)\n            if provider == \"aws\" and (\n                args.output_bucket or args.output_bucket_no_assume\n            ):\n                output_bucket = args.output_bucket\n                bucket_session = audit_info.audit_session\n                # Check if -D was input\n                if args.output_bucket_no_assume:\n                    output_bucket = args.output_bucket_no_assume\n                    bucket_session = audit_info.original_session\n                send_to_s3_bucket(\n                    audit_output_options.output_filename,\n                    args.output_directory,\n                    mode,\n                    output_bucket,\n                    bucket_session,\n                )\n\n    # Resolve previous fails of Security Hub\n    if provider == \"aws\" and args.security_hub and not args.skip_sh_update:\n        resolve_security_hub_previous_findings(\n            args.output_directory, args.output_filename, audit_info\n        )\n\n    # Display summary table\n    if not args.only_logs:\n        display_summary_table(\n            findings,\n            audit_info,\n            audit_output_options,\n            provider,\n        )\n\n        if compliance_framework and findings:\n            for compliance in compliance_framework:\n                # Display compliance table\n                display_compliance_table(\n                    findings,\n                    bulk_checks_metadata,\n                    compliance,\n                    audit_output_options.output_filename,\n                    audit_output_options.output_directory,\n                )\n\n    # If custom checks were passed, remove the modules\n    if checks_folder:\n        remove_custom_checks_module(checks_folder, provider)\n\n    # If there are failed findings exit code 3, except if -z is input\n    if not args.ignore_exit_code_3 and stats[\"total_fail\"] > 0:\n        sys.exit(3)\n\n\nif __name__ == \"__main__\":\n    prowler()\n", "path": "prowler/__main__.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport os\nimport sys\n\nfrom prowler.lib.banner import print_banner\nfrom prowler.lib.check.check import (\n    bulk_load_checks_metadata,\n    bulk_load_compliance_frameworks,\n    exclude_checks_to_run,\n    exclude_services_to_run,\n    execute_checks,\n    list_categories,\n    list_services,\n    parse_checks_from_folder,\n    print_categories,\n    print_checks,\n    print_compliance_frameworks,\n    print_compliance_requirements,\n    print_services,\n    remove_custom_checks_module,\n)\nfrom prowler.lib.check.checks_loader import load_checks_to_execute\nfrom prowler.lib.check.compliance import update_checks_metadata_with_compliance\nfrom prowler.lib.cli.parser import ProwlerArgumentParser\nfrom prowler.lib.logger import logger, set_logging_config\nfrom prowler.lib.outputs.compliance import display_compliance_table\nfrom prowler.lib.outputs.html import add_html_footer, fill_html_overview_statistics\nfrom prowler.lib.outputs.json import close_json\nfrom prowler.lib.outputs.outputs import extract_findings_statistics, send_to_s3_bucket\nfrom prowler.lib.outputs.slack import send_slack_message\nfrom prowler.lib.outputs.summary_table import display_summary_table\nfrom prowler.providers.aws.lib.security_hub.security_hub import (\n    resolve_security_hub_previous_findings,\n)\nfrom prowler.providers.common.allowlist import set_provider_allowlist\nfrom prowler.providers.common.audit_info import (\n    set_provider_audit_info,\n    set_provider_execution_parameters,\n)\nfrom prowler.providers.common.outputs import set_provider_output_options\nfrom prowler.providers.common.quick_inventory import run_provider_quick_inventory\n\n\ndef prowler():\n    # Parse Arguments\n    parser = ProwlerArgumentParser()\n    args = parser.parse()\n\n    # Save Arguments\n    provider = args.provider\n    checks = args.checks\n    excluded_checks = args.excluded_checks\n    excluded_services = args.excluded_services\n    services = args.services\n    categories = args.categories\n    checks_file = args.checks_file\n    checks_folder = args.checks_folder\n    severities = args.severity\n    compliance_framework = args.compliance\n\n    if not args.no_banner:\n        print_banner(args)\n\n    # We treat the compliance framework as another output format\n    if compliance_framework:\n        args.output_modes.extend(compliance_framework)\n\n    # Set Logger configuration\n    set_logging_config(args.log_level, args.log_file, args.only_logs)\n\n    if args.list_services:\n        print_services(list_services(provider))\n        sys.exit()\n\n    # Load checks metadata\n    logger.debug(\"Loading checks metadata from .metadata.json files\")\n    bulk_checks_metadata = bulk_load_checks_metadata(provider)\n\n    if args.list_categories:\n        print_categories(list_categories(bulk_checks_metadata))\n        sys.exit()\n\n    bulk_compliance_frameworks = {}\n    # Load compliance frameworks\n    logger.debug(\"Loading compliance frameworks from .json files\")\n\n    bulk_compliance_frameworks = bulk_load_compliance_frameworks(provider)\n    # Complete checks metadata with the compliance framework specification\n    update_checks_metadata_with_compliance(\n        bulk_compliance_frameworks, bulk_checks_metadata\n    )\n    if args.list_compliance:\n        print_compliance_frameworks(bulk_compliance_frameworks)\n        sys.exit()\n    if args.list_compliance_requirements:\n        print_compliance_requirements(\n            bulk_compliance_frameworks, args.list_compliance_requirements\n        )\n        sys.exit()\n\n    # Load checks to execute\n    checks_to_execute = load_checks_to_execute(\n        bulk_checks_metadata,\n        bulk_compliance_frameworks,\n        checks_file,\n        checks,\n        services,\n        severities,\n        compliance_framework,\n        categories,\n        provider,\n    )\n\n    # If -l/--list-checks passed as argument, print checks to execute and quit\n    if args.list_checks:\n        print_checks(provider, sorted(checks_to_execute), bulk_checks_metadata)\n        sys.exit()\n\n    # Set the audit info based on the selected provider\n    audit_info = set_provider_audit_info(provider, args.__dict__)\n\n    # Import custom checks from folder\n    if checks_folder:\n        parse_checks_from_folder(audit_info, checks_folder, provider)\n\n    # Exclude checks if -e/--excluded-checks\n    if excluded_checks:\n        checks_to_execute = exclude_checks_to_run(checks_to_execute, excluded_checks)\n\n    # Exclude services if --excluded-services\n    if excluded_services:\n        checks_to_execute = exclude_services_to_run(\n            checks_to_execute, excluded_services, provider\n        )\n\n    # Once the audit_info is set and we have the eventual checks based on the resource identifier,\n    # it is time to check what Prowler's checks are going to be executed\n    if audit_info.audit_resources:\n        checks_to_execute = set_provider_execution_parameters(provider, audit_info)\n\n    # Sort final check list\n    checks_to_execute = sorted(checks_to_execute)\n\n    # Parse Allowlist\n    allowlist_file = set_provider_allowlist(provider, audit_info, args)\n\n    # Set output options based on the selected provider\n    audit_output_options = set_provider_output_options(\n        provider, args, audit_info, allowlist_file, bulk_checks_metadata\n    )\n\n    # Run the quick inventory for the provider if available\n    if hasattr(args, \"quick_inventory\") and args.quick_inventory:\n        run_provider_quick_inventory(provider, audit_info, args)\n        sys.exit()\n\n    # Execute checks\n    findings = []\n    if len(checks_to_execute):\n        findings = execute_checks(\n            checks_to_execute, provider, audit_info, audit_output_options\n        )\n    else:\n        logger.error(\n            \"There are no checks to execute. Please, check your input arguments\"\n        )\n\n    # Extract findings stats\n    stats = extract_findings_statistics(findings)\n\n    if args.slack:\n        if \"SLACK_API_TOKEN\" in os.environ and \"SLACK_CHANNEL_ID\" in os.environ:\n            _ = send_slack_message(\n                os.environ[\"SLACK_API_TOKEN\"],\n                os.environ[\"SLACK_CHANNEL_ID\"],\n                stats,\n                provider,\n                audit_info,\n            )\n        else:\n            logger.critical(\n                \"Slack integration needs SLACK_API_TOKEN and SLACK_CHANNEL_ID environment variables (see more in https://docs.prowler.cloud/en/latest/tutorials/integrations/#slack).\"\n            )\n            sys.exit(1)\n\n    if args.output_modes:\n        for mode in args.output_modes:\n            # Close json file if exists\n            if \"json\" in mode:\n                close_json(\n                    audit_output_options.output_filename, args.output_directory, mode\n                )\n            if mode == \"html\":\n                add_html_footer(\n                    audit_output_options.output_filename, args.output_directory\n                )\n                fill_html_overview_statistics(\n                    stats, audit_output_options.output_filename, args.output_directory\n                )\n            # Send output to S3 if needed (-B / -D)\n            if provider == \"aws\" and (\n                args.output_bucket or args.output_bucket_no_assume\n            ):\n                output_bucket = args.output_bucket\n                bucket_session = audit_info.audit_session\n                # Check if -D was input\n                if args.output_bucket_no_assume:\n                    output_bucket = args.output_bucket_no_assume\n                    bucket_session = audit_info.original_session\n                send_to_s3_bucket(\n                    audit_output_options.output_filename,\n                    args.output_directory,\n                    mode,\n                    output_bucket,\n                    bucket_session,\n                )\n\n    # Resolve previous fails of Security Hub\n    if provider == \"aws\" and args.security_hub and not args.skip_sh_update:\n        resolve_security_hub_previous_findings(\n            audit_output_options.output_directory,\n            audit_output_options.output_filename,\n            audit_info,\n        )\n\n    # Display summary table\n    if not args.only_logs:\n        display_summary_table(\n            findings,\n            audit_info,\n            audit_output_options,\n            provider,\n        )\n\n        if compliance_framework and findings:\n            for compliance in compliance_framework:\n                # Display compliance table\n                display_compliance_table(\n                    findings,\n                    bulk_checks_metadata,\n                    compliance,\n                    audit_output_options.output_filename,\n                    audit_output_options.output_directory,\n                )\n\n    # If custom checks were passed, remove the modules\n    if checks_folder:\n        remove_custom_checks_module(checks_folder, provider)\n\n    # If there are failed findings exit code 3, except if -z is input\n    if not args.ignore_exit_code_3 and stats[\"total_fail\"] > 0:\n        sys.exit(3)\n\n\nif __name__ == \"__main__\":\n    prowler()\n", "path": "prowler/__main__.py"}]}