Пример #1
0
def main():
    """Main"""
    # Parse commandline arguments
    parser = FinfoArgumentParser(config_file=resilient.get_config_file())
    opts = parser.parse_args()

    # Connect to Resilient
    client = resilient.get_client(opts)

    # If no field is specified, list them all
    if not opts.fieldname:
        if opts.types:
            list_types(client)
        elif opts.field_values:
            list_fields_values(client, opts.field_type)
        elif opts.csv:
            list_fields_csv(client, opts.field_type)
        else:
            list_fields(client, opts.field_type)
        exit(0)

    # Find the field and display its properties
    field_data = find_field(client, opts.fieldname, opts.field_type)
    if field_data:
        if opts.json:
            print_json(field_data)
        else:
            print_details(field_data)
        exit(0)
    else:
        print(u"Field '{}' was not found.".format(opts.fieldname))
        exit(1)
Пример #2
0
 def xtest_with_env_variable(self, monkeypatch, tmp_config_file):
     """
     Test with environment variable $APP_CONFIG_FILE.
     """
     monkeypatch.setenv("APP_CONFIG_FILE", str(tmp_config_file))
     result = resilient.get_config_file()
     assert result == tmp_config_file
Пример #3
0
 def test_with_filename_exists_local(self, mock_os_path_exists):
     """
     Test with filename specified and not exists in home path.
     """
     test_file_name = "test_file"
     result = resilient.get_config_file(filename=test_file_name)
     assert result == test_file_name
Пример #4
0
    def __init__(self):
        super(KeyringUtils, self).__init__()

        config_file = resilient.get_config_file()
        print(u"Configuration file: {}".format(config_file))

        # Read configuration options.
        if config_file:
            config_path = resilient.ensure_unicode(config_file)
            config_path = os.path.expanduser(config_path)
            if os.path.exists(config_path):
                try:
                    self.config = configparser.ConfigParser(interpolation=None)
                    with open(config_path, 'r', encoding='utf-8') as f:
                        first_byte = f.read(1)
                        if first_byte != u'\ufeff':
                            # Not a BOM, no need to skip first byte
                            f.seek(0)
                        self.config.read_file(f)
                except Exception as exc:
                    logger.warn(u"Couldn't read config file '%s': %s", config_path, exc)
                    self.config = None
            else:
                logger.warn(u"Couldn't read config file '%s'", config_file)
        else:
            logger.warn(u"Couldn't read config file")
Пример #5
0
 def test_generate_with_env_variable(self, monkeypatch, tmp_config_file):
     """
     Test generate with environment variable $APP_CONFIG_FILE.
     """
     monkeypatch.setenv("APP_CONFIG_FILE", str(tmp_config_file))
     result = get_config_file(generate_filename=True)
     assert result == tmp_config_file
Пример #6
0
def main():
    parser = ExampleArgumentParser(config_file=resilient.get_config_file())
    opts = parser.parse_args()

    # Create SimpleClient for a REST connection to the Resilient services
    client = resilient.get_client(opts)

    if opts["create"]:
        create_incident(client, opts["create"], opts["attach"])

    if opts["list"]:
        show_incident_list(client, opts["query"])

    if opts["get"]:
        generic_get(client, opts["get"])

    if opts["post"]:
        generic_post(client, opts["post"][0], opts["post"][1])

    if opts["update"]:
        generic_update(client, opts["update"][0], opts["update"][1])

    if opts["patch"]:
        generic_patch(client, opts["patch"][0], opts["patch"][1])

    if opts["delete"]:
        generic_delete(client, opts["delete"])

    if opts["search"]:
        generic_search(client, opts["search"])
def generate_code(args):
    """generate template code components from functions"""
    parser = AppArgumentParser(config_file=resilient.get_config_file())
    (opts, extra) = parser.parse_known_args()
    client = resilient.get_client(opts)

    if args.cmd == "extract" and args.output:
        extract_to_res(client, args.exportfile, args.messagedestination,
                       args.function, args.workflow, args.rule, args.field,
                       args.datatable, args.task, args.script,
                       args.artifacttype, args.output, args.zip)
    elif args.reload:
        codegen_reload_package(client, args)
    elif args.package:
        # codegen an installable package
        output_base = os.path.join(os.curdir, args.package)
        codegen_package(client, args.exportfile, args.package,
                        args.messagedestination, args.function, args.workflow,
                        args.rule, args.field, args.datatable, args.task,
                        args.script, args.artifacttype,
                        os.path.expanduser(output_base))
    elif args.function:
        # codegen a component for one or more functions
        if len(args.function) > 1:
            default_name = "functions.py"
        else:
            default_name = "{}.py".format(args.function[0])
        output_dir = os.path.expanduser(opts["componentsdir"] or os.curdir)
        output_file = args.output or default_name
        if not output_file.endswith(".py"):
            output_file = output_file + ".py"
        codegen_functions(client, args.exportfile, args.function,
                          args.workflow, args.rule, args.artifacttype,
                          output_dir, output_file)
def selftest(args):
    """loop through every selftest for every eligible package, call and store returned state,
        print out package and their selftest states"""

    components = defaultdict(list)

    # custom entry_point only for selftest functions
    selftest_entry_points = [
        ep for ep in pkg_resources.iter_entry_points(
            'resilient.circuits.selftest')
    ]
    for ep in selftest_entry_points:
        components[ep.dist].append(ep)

    if len(selftest_entry_points) == 0:
        LOG.info("No selftest entry points found.")
        return None

    # Generate opts array necessary for ResilientComponent instantiation
    opts = AppArgumentParser(
        config_file=resilient.get_config_file()).parse_args("", None)

    # make a copy
    install_list = list(args.install_list) if args.install_list else []

    for dist, component_list in components.items():
        if args.install_list is None or dist.project_name in install_list:
            # remove name from list
            if dist.project_name in install_list:
                install_list.remove(dist.project_name)

            # add an entry for the package
            LOG.info("%s: ", dist.project_name)
            for ep in component_list:
                # load the entry point
                f_selftest = ep.load()

                try:
                    # f_selftest is the selftest function, we pass the selftest resilient options in case it wants to use it
                    start_time_milliseconds = int(round(time.time() * 1000))

                    status = f_selftest(opts)

                    end_time_milliseconds = int(round(time.time() * 1000))

                    delta_milliseconds = end_time_milliseconds - start_time_milliseconds
                    delta_seconds = delta_milliseconds / 1000

                    if status["state"] is not None:
                        LOG.info("\t%s: %s, Elapsed time: %f seconds", ep.name,
                                 status["state"], delta_seconds)
                except Exception as e:
                    LOG.error("Error while calling %s. Exception: %s", ep.name,
                              str(e))
                    continue

    # any missed packages?
    if len(install_list):
        LOG.warning("%s not found. Check package name(s)", install_list)
Пример #9
0
 def test_generate_with_filename(self):
     """
     Test generate with filename specified.
     """
     test_file_name = "test_file"
     result = get_config_file(filename=test_file_name,
                              generate_filename=True)
     assert result == test_file_name
Пример #10
0
 def __init__(self, auto_load_components=True, config_file=None):
     super(App, self).__init__()
     # Read the configuration options
     self.action_component = None
     self.component_loader = None
     self.auto_load_components = auto_load_components
     self.config_file = config_file or resilient.get_config_file()
     self.do_initialization()
Пример #11
0
def main():
    """
    program main
    """

    config_file = resilient.get_config_file()
    parser = ExampleArgumentParser(config_file)
    opts = parser.parse_args()

    inc_types = opts["itype"]
    inc_queue = opts["queue"]

    # Create SimpleClient for a REST connection to the Resilient services
    client = resilient.get_client(opts)

    # Discovered Date will be set to the current time
    time_now = int(time.time() * 1000)

    try:
        uri = '/incidents'

        rf_config = configparser.ConfigParser()
        rf_config.read(config_file)
        rf_opts = dict(rf_config.items('fn_risk_fabric'))
        result = get_action_plans(rf_opts)

        for ap in result:

            if 'AssignToQueueName' in ap and ap[
                    'AssignToQueueName'] == inc_queue:

                # Construct the basic incident DTO that will be posted
                description = ap['Notes'] if 'Notes' in ap else ""
                ActionPlanGUID = ap['ActionPlanGUID']
                properties = {"rf_actionplanguid": ActionPlanGUID}
                new_incident = {
                    "name": ap['Title'],
                    "description": description,
                    "incident_type_ids": inc_types,
                    "properties": properties,
                    "discovered_date": time_now
                }

                # Create the incident
                incident = client.post(uri, new_incident)
                inc_id = incident["id"]

                params = {
                    'ActionPlanGUID': ActionPlanGUID,
                    'Comment': "Created Resilient Incident ID #" + str(inc_id)
                }
                result = set_action_plan_comment(rf_opts, params)

                print("Created incident {}".format(inc_id))

    except resilient.SimpleHTTPException as ecode:
        print("create failed : {}".format(ecode))
Пример #12
0
 def test_with_filename_not_exists_local(self, mock_os_path_not_exists):
     """
     Test with filename specified and exists in home path.
     """
     test_file_name = "test_file"
     test_file_abs = os.path.expanduser(
         os.path.join("~", ".resilient", test_file_name))
     result = resilient.get_config_file(filename=test_file_name)
     assert result == test_file_abs
def main():
    """Main"""
    parser = ExportArgumentParser(config_file=resilient.get_config_file())
    opts = parser.parse_args()

    # Export the data
    export_context = ExportContext(opts)
    export_context.export_json()

    print("Done.")
Пример #14
0
def customize_resilient(args):
    """import customizations to the resilient server"""
    parser = AppArgumentParser(config_file=resilient.get_config_file())
    (opts, extra) = parser.parse_known_args()
    client = resilient.get_client(opts)

    # Call each of the 'customize' entry points to get type definitions,
    # then apply them to the resilient server
    entry_points = pkg_resources.iter_entry_points('resilient.circuits.customize')
    do_customize_resilient(client, entry_points, args.yflag, args.install_list)
def main():
    """Main"""

    # Parse the commandline arguments and config file
    config = resilient.get_config_file()
    print("Configuration file: {}".format(config))
    parser = resilient.ArgumentParser(config_file=config)
    opts = parser.parse_args()

    # Create SimpleClient for a REST connection to the Resilient services
    resilient_client = resilient.get_client(opts)

    # Report the list of users and groups
    report_users_and_groups(resilient_client)
Пример #16
0
def main():
    """main"""

    # Parse the commandline arguments and config file
    config = resilient.get_config_file()
    print("Configuration file: {}".format(config))
    parser = ReportArgumentParser(config_file=config)
    opts = parser.parse_args()

    # Create SimpleClient for a REST connection to the Resilient services
    resilient_client = resilient.get_client(opts)

    # Do the reports
    phases_report(opts, resilient_client)
Пример #17
0
 def __init__(self,
              auto_load_components=True,
              config_file=None,
              ALLOW_UNRECOGNIZED=False,
              IS_SELFTEST=False):
     super(App, self).__init__()
     # Read the configuration options
     self.ALLOW_UNRECOGNIZED = ALLOW_UNRECOGNIZED
     resilient_constants.ALLOW_UNRECOGNIZED = ALLOW_UNRECOGNIZED
     self.IS_SELFTEST = IS_SELFTEST
     self.action_component = None
     self.component_loader = None
     self.auto_load_components = auto_load_components
     self.config_file = config_file or get_config_file()
     self.do_initialization()
def main():
    """
    program main
    """

    config_file = resilient.get_config_file()
    parser = ExampleArgumentParser(config_file)
    opts = parser.parse_args()

    inc_types = opts["itype"]
    inc_limit = opts["limit"]

    # Create SimpleClient for a REST connection to the Resilient services
    client = resilient.get_client(opts)

    # Discovered Date will be set to the current time
    time_now = int(time.time() * 1000)

    try:
        uri = '/incidents'

        rf_config = configparser.ConfigParser()
        rf_config.read(config_file)
        rf_opts = dict(rf_config.items('fn_risk_fabric'))
        params = {'Limit': inc_limit}
        result = get_risk_model_instances(rf_opts, params)

        for ap in result['Records']:

            # Construct the basic incident DTO that will be posted
            inc_name = ap['RiskModelName']
            inc_description = ap['Threats'] + ', ' + ap[
                'FocusEntityCaption'] + ', #' + str(ap['ID'])
            new_incident = {
                "name": inc_name,
                "description": inc_description,
                "incident_type_ids": inc_types,
                "discovered_date": time_now
            }

            # Create the incident
            incident = client.post(uri, new_incident)
            inc_id = incident["id"]

            print("Created incident {}".format(inc_id))

    except resilient.SimpleHTTPException as ecode:
        print("create failed : {}".format(ecode))
def main():
    """
    program main
    """

    parser = ExampleArgumentParser(config_file=resilient.get_config_file())
    opts = parser.parse_args()

    inc_name = opts["name"]
    inc_desc = opts["description"]
    inc_types = opts["itype"]

    # Create SimpleClient for a REST connection to the Resilient services
    client = resilient.get_client(opts)

    # Discovered Date will be set to the current time
    time_now = int(time.time() * 1000)

    # Construct the basic incident DTO that will be posted
    new_incident = {
        "name": inc_name,
        "description": inc_desc,
        "incident_type_ids": inc_types,
        "discovered_date": time_now,
        "properties": {}
    }

    # Add the specified values for any custom fields,
    # per the command-line arguments provided.
    # Within the incident JSON structure, the values for custom fields
    # are all contained within a dictionary value named 'properties'.
    for custom in opts["custom"]:
        (field_name, field_value) = custom.split("=", 1)
        print("{} = {}".format(field_name, field_value))
        new_incident["properties"][field_name] = field_value

    try:
        uri = '/incidents'

        # Create the incident
        incident = client.post(uri, new_incident)

        inc_id = incident["id"]

        print("Created incident {}".format(inc_id))

    except resilient.SimpleHTTPException as ecode:
        print("create failed : {}".format(ecode))
Пример #20
0
def check_connect():
    """
    Use openssl and python requests to check the connection with Resilient
    :return:
    """
    arg_parser = resilient.ArgumentParser(resilient.get_config_file())
    host = arg_parser.getopt("resilient", "host")
    #
    # Use Openssl first
    #
    print("-------------------------------------")
    print("Using openssl to connect to resilient")
    print("-------------------------------------")
    command = "openssl s_client -connect {}:443".format(host)
    user = arg_parser.getopt("resilient", "email")
    password = arg_parser.getopt("resilient", "password")
    process = subprocess.Popen("/bin/bash",
                               stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE)
    out, err = process.communicate(command)
    cafile = arg_parser.getopt("resilient", "cafile")
    verify = True
    if cafile is not None and cafile == "false":
        verify = False
    print(out)
    if err is not None:
        print(err)

    print("---------------------------------------------")
    print("Using python requests to connect to resilient")
    print("---------------------------------------------")

    rest_url = "https://{}:443/rest/session".format(host)
    data = '{"email": "' + user + '","password":"******", "interactive": true}'
    try:
        header = {"Content-Type": "application/json"}
        resp = requests.post(rest_url,
                             data=data,
                             headers=header,
                             verify=verify)
        print("\tResponse: " + str(resp))

    except Exception as e:
        print("\tConnection failed!!")
        print("\t" + str(e))
Пример #21
0
def create_authenticated_client():
    """create_authenticated_client uses the resilient package
    to gather values from a standard app.config file; the configuration file
    used for an Integration Server or App Host App.
    This means all credentials needed to run this module can be kept
    separate and we can also avoid var prompts.
    Note: If your running this module on a host other than localhost,
    that host needs to have an app.config file or you need to copy one over.
    :return: An authenticated rest client to CP4S or Resilient
    :rtype: SimpleClient
    """
    import resilient
    # Create Resilient API Client
    resilient_parser = resilient.ArgumentParser(
        config_file=resilient.get_config_file())
    resilient_opts = resilient_parser.parse_known_args()
    # Instantiate a client using the gathered opts
    return resilient.get_client(resilient_opts[0])
Пример #22
0
def get_resilient_client(path_config_file=None):
    """
    Return a SimpleClient for Resilient REST API using configurations
    options from provided path_config_file or from ~/.resilient/app.config

    :param path_config_file: Path to app.config file to use
    :return: SimpleClient for Resilient REST API
    :rtype: SimpleClient
    """
    LOG.info("Connecting to Resilient Appliance...")

    if not path_config_file:
        path_config_file = get_config_file()

    config_parser = ArgumentParser(config_file=path_config_file)
    opts = config_parser.parse_known_args()[0]

    return get_client(opts)
def main():
    parser = ExportArgumentParser(config_file=resilient.get_config_file())
    opts = parser.parse_args()

    first_json = get_json_from_file(opts.get("first_json_file"))
    second_json = get_json_from_file(opts.get("second_json_file"))

    if first_json is None or second_json is None:
        raise Exception("Invalid file provided.")

    if first_json.get("incidents") is None or second_json.get(
            "incidents") is None:
        raise Exception("Invalid JSON provided, incidents object not found.")

    first_incidents = first_json.get("incidents")

    second_incidents_array = second_json.get("incidents")
    second_incidents = []

    for incident in second_incidents_array:
        incident_id = incident.get("id")
        if incident_id is not None:
            second_incidents.append(incident_id)

    incidents = []

    for incident in first_incidents:
        incident_id = incident.get("id")
        # if valid incident
        if incident_id is None:
            continue

        # if the incident already exists, we don't want to add it
        if incident_id not in second_incidents:
            incidents.append(incident)

    incidents += second_incidents_array

    with open(opts.get("output_json_file"), "w") as outfile:
        json.dump({"incidents": incidents}, outfile)
        outfile.write("\n")

    print("Successfully merged JSON files into {}.".format(
        opts.get("output_json_file")))
def main():
    """
    program main
    """

    parser = ExampleArgumentParser(config_file=resilient.get_config_file())
    opts = parser.parse_args()

    # Create SimpleClient for a REST connection to the Resilient services
    client = resilient.get_client(opts)

    inc_id = opts["incid"]
    desc = opts["desc"]

    try:
        uri = '/incidents/{}'.format(inc_id)

        incident = client.get(uri)

        # Create a patch object.  You need to pass it the base object (the thing being patched).  This
        # object contains the old values, which are sent to the server.
        patch = resilient.Patch(incident)

        patch.add_value("description", desc)

        print('''
At this point, we have a copy of the specified incident.  If you want to trigger a conflict to see
what will happen, then you can do so now.

Press the Enter key to continue''')
        input()

        # Apply the patch and overwrite any conflicts.
        client.patch(uri, patch, overwrite_conflict=True)

        # Confirm that our change was applied.  This is not something that you'd typically need to do since the
        # patch applied successfully, but this illustrates that the change was applied for the purposes of this
        # example.
        assert desc == client.get(uri)["description"]

    except resilient.SimpleHTTPException as ecode:
        print("patch failed : {}".format(ecode))
Пример #25
0
    def connect(self):
        print("----------------")
        print("Ready to connect")
        print("----------------")
        print("Read config information from app.confg ...")
        arg_parser = resilient.ArgumentParser(
            resilient.get_config_file()).parse_args(args=self.other_args)
        host = arg_parser.host
        email = arg_parser.email
        password = arg_parser.password
        org = arg_parser.org
        api_key_id = arg_parser.api_key_id
        api_key_secret = arg_parser.api_key_secret

        cafile = arg_parser.cafile

        verify = True
        if cafile is not None and cafile == "false":
            verify = False
        url = "https://{}:443".format(host)
        print("Connecting to {} using user:{}, and org:{}".format(
            url, email, org))
        print("Validate cert: {}".format(verify))

        args = {"base_url": url, "verify": verify, "org_name": org}

        self.res_client = resilient.SimpleClient(**args)

        if email is not None and password is not None:
            session = self.res_client.connect(email, password)

            if session is not None:
                user_name = session.get("user_displayname", "Not found")
                print("User display name is : {}".format(user_name))

            print("Done")
        else:
            self.res_client.set_api_key(api_key_id=api_key_id,
                                        api_key_secret=api_key_secret)
Пример #26
0
def get_configs(path_config_file=None, ALLOW_UNRECOGNIZED=False):
    """
    Gets all the configs that are defined in the app.config file
    Uses the path to the config file from the parameter
    Or uses the `get_config_file()` method in resilient if None

    :param path_config_file: path to the app.config to parse
    :type path_config_file: str
    :param ALLOW_UNRECOGNIZED: bool to specify if AppArgumentParser will allow unknown comandline args or not. Default is False
    :type ALLOW_UNRECOGNIZED: bool
    :return: dictionary of all the configs in the app.config file
    :rtype: dict
    """
    from resilient import get_config_file
    from resilient_circuits.app_argument_parser import AppArgumentParser

    if not path_config_file:
        path_config_file = get_config_file()

    configs = AppArgumentParser(config_file=path_config_file).parse_args(
        ALLOW_UNRECOGNIZED=ALLOW_UNRECOGNIZED)
    return configs
Пример #27
0
def main():
    """
    program main
    """

    parser = ExampleArgumentParser(config_file=resilient.get_config_file())
    opts = parser.parse_args()

    inc_name = opts["name"]
    inc_desc = opts["description"]
    inc_types = opts["itype"]

    # Create SimpleClient for a REST connection to the Resilient services
    client = resilient.get_client(opts)

    # Discovered Date will be set to the current time
    time_now = int(time.time() * 1000)

    # Construct the basic incident DTO that will be posted
    new_incident = {
        "name": inc_name,
        "description": inc_desc,
        "incident_type_ids": inc_types,
        "discovered_date": time_now
    }

    try:
        uri = '/incidents'

        # Create the incident
        incident = client.post(uri, new_incident)

        inc_id = incident["id"]

        print("Created incident {}".format(inc_id))

    except resilient.SimpleHTTPException as ecode:
        print("create failed : {}".format(ecode))
Пример #28
0
    def __init__(self, config_file=None):
        self.config_file = config_file or resilient.get_config_file()
        super(OptParser, self).__init__(config_file=self.config_file)
        #
        #   Note this is a trick used by resilient-circuits. resilient.ArgumentParser will
        #   validate the arguments of the command line. Since we use command line
        #   argument of input/output files, we don't want that validation, so we
        #   erase them before we call parse_args(). So parse_args() only
        #   reads from app.config
        #
        sys.argv = sys.argv[0:1]
        self.opts = self.parse_args()

        if self.config:
            for section in self.config.sections():
                #
                # Handle sections other than [resilient] in app.config
                #
                items = dict((item.lower(), self.config.get(section, item))
                             for item in self.config.options(section))
                self.opts.update({section: items})

            resilient.parse_parameters(self.opts)
Пример #29
0
    def do_function(self, arg):
        """Execute a function"""
        if not arg:
            print("function command requires a function-name")
            return

        parser = AppArgumentParser(config_file=resilient.get_config_file())
        (opts, more) = parser.parse_known_args()
        client = resilient.get_client(opts)

        args = iter(shlex.split(arg))
        try:
            function_name = next(args)
            function_def = client.get("/functions/{}?handle_format=names".format(function_name))
            param_defs = dict({fld["uuid"]: fld for fld in client.get("/types/__function/fields?handle_format=names")})
            function_params = {}
            for param in function_def["view_items"]:
                param_uuid = param["content"]
                param_def = param_defs[param_uuid]
                prompt = "{} ({}, {}): ".format(param_def["name"], param_def["input_type"], param_def["tooltip"])
                try:
                    arg = next(args)
                except StopIteration:
                    arg = None
                function_params[param_def["name"]] = get_input(param_def["input_type"], prompt, arg)

            action_message = {
                "function": {
                    "name": function_name
                },
                "inputs": function_params
            }
            message = json.dumps(action_message, indent=2)
            print(message)
            self._submit_action("function", message)
        except Exception as e:
            print(e)
Пример #30
0
    def __init__(self, config_file=None):

        # Temporary logging handler until the real one is created later
        temp_handler = logging.StreamHandler()
        temp_handler.setFormatter(
            logging.Formatter(
                '%(asctime)s %(levelname)s [%(module)s] %(message)s'))
        temp_handler.setLevel(logging.INFO)
        logging.getLogger().addHandler(temp_handler)
        config_file = config_file or resilient.get_config_file()
        super(AppArgumentParser, self).__init__(config_file=config_file)

        default_components_dir = self.getopt(
            self.DEFAULT_APP_SECTION,
            "componentsdir") or self.DEFAULT_COMPONENTS_DIR
        default_noload = self.getopt(self.DEFAULT_APP_SECTION, "noload") or ""
        default_log_dir = self.getopt(self.DEFAULT_APP_SECTION,
                                      "logdir") or APP_LOG_DIR
        default_log_level = self.getopt(self.DEFAULT_APP_SECTION,
                                        "loglevel") or self.DEFAULT_LOG_LEVEL
        default_log_file = self.getopt(self.DEFAULT_APP_SECTION,
                                       "logfile") or self.DEFAULT_LOG_FILE

        # STOMP port is usually 65001
        default_stomp_port = self.getopt(
            self.DEFAULT_APP_SECTION, "stomp_port") or self.DEFAULT_STOMP_PORT
        # For some environments the STOMP TLS certificate will be different from the REST API cert
        default_stomp_cafile = self.getopt(self.DEFAULT_APP_SECTION,
                                           "stomp_cafile") or None

        default_stomp_url = self.getopt(self.DEFAULT_APP_SECTION,
                                        "stomp_host") or self.getopt(
                                            self.DEFAULT_APP_SECTION, "host")
        default_stomp_timeout = self.getopt(
            self.DEFAULT_APP_SECTION,
            "stomp_timeout") or self.DEFAULT_STOMP_TIMEOUT
        default_stomp_max_retries = self.getopt(
            self.DEFAULT_APP_SECTION,
            "stomp_max_retries") or self.DEFAULT_STOMP_MAX_RETRIES
        default_max_connection_retries = self.getopt(
            self.DEFAULT_APP_SECTION,
            "max_connection_retries") or self.DEFAULT_MAX_CONNECTION_RETRIES

        default_no_prompt_password = self.getopt(
            self.DEFAULT_APP_SECTION,
            "no_prompt_password") or self.DEFAULT_NO_PROMPT_PASS
        default_no_prompt_password = self._is_true(default_no_prompt_password)

        default_test_actions = self._is_true(
            self.getopt(self.DEFAULT_APP_SECTION, "test_actions")) or False
        default_test_host = self.getopt(self.DEFAULT_APP_SECTION,
                                        "test_host") or None
        default_test_port = self.getopt(self.DEFAULT_APP_SECTION,
                                        "test_port") or None
        default_log_responses = self.getopt(self.DEFAULT_APP_SECTION,
                                            "log_http_responses") or ""
        default_resource_prefix = self.getopt(self.DEFAULT_APP_SECTION,
                                              "resource_prefix") or None
        default_num_workers = self.getopt(
            self.DEFAULT_APP_SECTION,
            "num_workers") or self.DEFAULT_NUM_WORKERS

        logging.getLogger().removeHandler(temp_handler)

        self.add_argument("--stomp-host",
                          type=str,
                          default=default_stomp_url,
                          help="Resilient server STOMP host url")
        self.add_argument("--stomp-port",
                          type=int,
                          default=default_stomp_port,
                          help="Resilient server STOMP port number")
        self.add_argument("--stomp-cafile",
                          type=str,
                          action="store",
                          default=default_stomp_cafile,
                          help="Resilient server STOMP TLS certificate")
        self.add_argument(
            "--stomp-timeout",
            type=int,
            action="store",
            default=os.environ.get('RESILIENT_STOMP_TIMEOUT',
                                   default_stomp_timeout),
            help="Resilient server STOMP timeout for connections")
        self.add_argument(
            "--stomp-max-retries",
            type=int,
            action="store",
            default=os.environ.get('RESILIENT_STOMP_MAX_RETRIES',
                                   default_stomp_max_retries),
            help="Resilient server STOMP max retries before failing")
        self.add_argument(
            "--max-connection-retries",
            type=int,
            action="store",
            default=os.environ.get('RESILIENT_MAX_CONNECTION_RETRIES') or 0
            if os.environ.get("APP_HOST_CONTAINER") else
            default_max_connection_retries,
            help=
            "Resilient max retries when connecting to Resilient or 0 for unlimited"
        )
        self.add_argument(
            "--resource-prefix",
            type=str,
            action="store",
            default=os.environ.get('RESOURCE_PREFIX', default_resource_prefix),
            help="Cloud Pak for Security resource path for host and STOMP URLs"
        )
        self.add_argument("--componentsdir",
                          type=str,
                          default=default_components_dir,
                          help="Circuits components auto-load directory")
        self.add_argument("--noload",
                          type=str,
                          default=default_noload,
                          help="List of components that should not be loaded")
        self.add_argument("--logdir",
                          type=str,
                          default=default_log_dir,
                          help="Directory for log files")
        self.add_argument("--loglevel",
                          type=str,
                          default=default_log_level,
                          help="Log level")
        self.add_argument("--logfile",
                          type=str,
                          default=default_log_file,
                          help="File to log to")
        self.add_argument("--no-prompt-password",
                          type=bool,
                          default=default_no_prompt_password,
                          help="Never prompt for password on stdin")
        self.add_argument("--test-actions",
                          action="store_true",
                          default=default_test_actions,
                          help="Enable submitting test actions?")
        self.add_argument("--test-host",
                          type=str,
                          action="store",
                          default=default_test_host,
                          help=("For use with --test-actions option. "
                                "Host or IP to bind test server to."))
        self.add_argument("--test-port",
                          type=int,
                          action="store",
                          default=default_test_port,
                          help=("For use with --test-actions option. "
                                "Port to bind test server to."))
        self.add_argument("--log-http-responses",
                          type=str,
                          default=default_log_responses,
                          help=("Log all responses from Resilient "
                                "REST API to this directory"))
        self.add_argument(
            "--num-workers",
            type=int,
            default=default_num_workers,
            help=("Number of FunctionWorkers to use. "
                  "Number of Functions that can run in parallel"))