def create_profilepackage(rules, addresses):
        device_groups = ['test_dg']
        devicegroup_objects = {'test_dg': collections.defaultdict(list)}
        devicegroup_objects['test_dg']['Addresses'] = addresses
        devicegroup_objects['test_dg']['all_active_child_firewalls'] = [
            "fake_firewall"
        ]
        devicegroup_exclusive_objects = {
            'test_dg': collections.defaultdict(list)
        }
        devicegroup_exclusive_objects["test_dg"]['SecurityPreRules'] = rules

        profilepackage = ProfilePackage(
            api_key='',
            pan_config=PanConfig('<_/>'),
            settings=ConfigurationSettings().get_config(),
            device_group_hierarchy_children={},
            device_group_hierarchy_parent={},
            device_groups_and_firewalls={},
            device_groups=device_groups,
            devicegroup_objects=devicegroup_objects,
            devicegroup_exclusive_objects=devicegroup_exclusive_objects,
            rule_limit_enabled=False,
            no_api=False)
        return profilepackage
    def create_profilepackage(shared_addresses, shared_addressgroups,
                              shared_securityprerules, shared_natprerules,
                              dg_addresses, dg_securityprerules):
        device_groups = ["shared"]
        devicegroup_objects = {
            "shared": collections.defaultdict(list),
            "test_dg": collections.defaultdict(list)
        }
        devicegroup_objects['shared']['all_child_device_groups'] = [
            "shared", "test_dg"
        ]
        devicegroup_objects["shared"]['Addresses'] = shared_addresses
        devicegroup_objects["shared"]['AddressGroups'] = shared_addressgroups
        devicegroup_objects["shared"][
            'SecurityPreRules'] = shared_securityprerules
        devicegroup_objects["shared"]['NATPreRules'] = shared_natprerules
        devicegroup_objects["test_dg"]['SecurityPreRules'] = dg_addresses
        devicegroup_objects["test_dg"]['NATPreRules'] = dg_securityprerules

        profilepackage = ProfilePackage(
            api_key='',
            pan_config=PanConfig('<_/>'),
            settings=ConfigurationSettings().get_config(),
            device_group_hierarchy_children={},
            device_group_hierarchy_parent={},
            device_groups_and_firewalls={},
            device_groups=device_groups,
            devicegroup_objects=devicegroup_objects,
            devicegroup_exclusive_objects={},
            rule_limit_enabled=False,
            no_api=False)
        return profilepackage
    def create_profilepackage(allowed_group_profile, pan_config):
        device_groups = ['test_dg']
        rules = pan_config.get_devicegroup_policy('SecurityPreRules',
                                                  'test_dg')
        devicegroup_exclusive_objects = {
            'test_dg': {
                'SecurityPreRules': rules,
                'SecurityPostRules': []
            }
        }

        settings = ConfigurationSettings().get_config()
        settings['Allowed Group Profiles'] = allowed_group_profile

        profilepackage = ProfilePackage(
            api_key='',
            pan_config=PanConfig('<_/>'),
            settings=settings,
            device_group_hierarchy_children={},
            device_group_hierarchy_parent={},
            device_groups_and_firewalls={},
            device_groups=device_groups,
            devicegroup_objects={},
            devicegroup_exclusive_objects=devicegroup_exclusive_objects,
            rule_limit_enabled=False,
            no_api=False)
        return profilepackage
    def create_profilepackage(pan_config):
        device_groups = ["shared"]
        settings = ConfigurationSettings().get_config()

        profilepackage = ProfilePackage(api_key='',
                                        pan_config=pan_config,
                                        settings=settings,
                                        device_group_hierarchy_children={},
                                        device_group_hierarchy_parent={},
                                        device_groups_and_firewalls={},
                                        device_groups=device_groups,
                                        devicegroup_objects={},
                                        devicegroup_exclusive_objects={},
                                        rule_limit_enabled=False,
                                        no_api=False)
        return profilepackage
 def create_profilepackage(pan_config, mandated_log_profile):
     device_groups = ['test_dg']
     settings = ConfigurationSettings().get_config()
     settings['Mandated Logging Profile'] = mandated_log_profile
     profilepackage = ProfilePackage(api_key='',
                                     pan_config=pan_config,
                                     settings=settings,
                                     device_group_hierarchy_children={},
                                     device_group_hierarchy_parent={},
                                     device_groups_and_firewalls={},
                                     device_groups=device_groups,
                                     devicegroup_objects={},
                                     devicegroup_exclusive_objects={},
                                     rule_limit_enabled=False,
                                     no_api=False)
     return profilepackage
    def create_profilepackage(services):
        device_groups = ["shared"]
        devicegroup_objects = {"shared": {}}
        devicegroup_objects["shared"]['Services'] = services

        profilepackage = ProfilePackage(
            api_key='',
            pan_config=PanConfig('<_/>'),
            settings=ConfigurationSettings().get_config(),
            device_group_hierarchy_children={},
            device_group_hierarchy_parent={},
            device_groups_and_firewalls={},
            device_groups=device_groups,
            devicegroup_objects=devicegroup_objects,
            devicegroup_exclusive_objects=[],
            rule_limit_enabled=False,
            no_api=False)
        return profilepackage
    def create_profilepackage(addresses, ignored_dns_prefixes):
        device_groups = ["shared"]
        devicegroup_objects = {"shared": {}}
        devicegroup_objects["shared"]['Addresses'] = addresses
        settings = ConfigurationSettings().get_config()
        settings['Ignored DNS Prefixes'] = ",".join(ignored_dns_prefixes)

        profilepackage = ProfilePackage(
            api_key='',
            pan_config=PanConfig('<_/>'),
            settings=settings,
            device_group_hierarchy_children={},
            device_group_hierarchy_parent={},
            device_groups_and_firewalls={},
            device_groups=device_groups,
            devicegroup_objects=devicegroup_objects,
            devicegroup_exclusive_objects={},
            rule_limit_enabled=False,
            no_api=False)
        return profilepackage
    def create_profilepackage(pan_config):
        device_groups = ["shared"]
        devicegroup_objects = {
            "shared": collections.defaultdict(list),
            "test_dg": collections.defaultdict(list)
        }
        devicegroup_objects['shared']['all_child_device_groups'] = [
            "shared", "test_dg"
        ]

        profilepackage = ProfilePackage(
            api_key='',
            pan_config=pan_config,
            settings=ConfigurationSettings().get_config(),
            device_group_hierarchy_children={},
            device_group_hierarchy_parent={},
            device_groups_and_firewalls={},
            device_groups=device_groups,
            devicegroup_objects=devicegroup_objects,
            devicegroup_exclusive_objects={},
            rule_limit_enabled=False,
            no_api=False)
        return profilepackage
    def create_profilepackage(shared_addresses, dg_addresses,
                              shared_address_groups, dg_address_groups):
        device_groups = ["shared", "test_dg"]
        device_group_hierarchy_parent = {"test_dg": "shared"}
        devicegroup_objects = {"shared": {}, "test_dg": {}}
        devicegroup_objects["shared"]['Addresses'] = shared_addresses
        devicegroup_objects["test_dg"]['Addresses'] = dg_addresses
        devicegroup_objects["shared"]['AddressGroups'] = shared_address_groups
        devicegroup_objects["test_dg"]['AddressGroups'] = dg_address_groups

        profilepackage = ProfilePackage(
            api_key='',
            pan_config=PanConfig('<_/>'),
            settings=ConfigurationSettings().get_config(),
            device_group_hierarchy_children={},
            device_group_hierarchy_parent=device_group_hierarchy_parent,
            device_groups_and_firewalls={},
            device_groups=device_groups,
            devicegroup_objects=devicegroup_objects,
            devicegroup_exclusive_objects={},
            rule_limit_enabled=False,
            no_api=False)
        return profilepackage
def main():
    description = """\
Retrieves PAN FW policy and checks it for various issues."""

    validator_descriptions = '\n'.join(
        f"{readable_name} - {description}"
        for readable_name, description, f in sorted(
            get_policy_validators().values()))
    epilog = f"""Here is a detailed list of the {len(get_policy_validators().keys())} supported validators:
{validator_descriptions}
"""

    parser = argparse.ArgumentParser(
        description=description,
        epilog=epilog,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--all",
                       help="Run validators on all Device Groups",
                       action='store_true')
    group.add_argument("--device-group",
                       help="Device Group to run through validator")
    parser.add_argument(
        "--validator",
        help="Only run specified validators (repeat for multiple)",
        choices=sorted(get_policy_validators().keys()),
        action='append')
    parser.add_argument("--quiet", help="Silence output", action='store_true')
    parser.add_argument(
        "--config",
        help=f"Config file to read (default is {DEFAULT_CONFIGFILE})",
        default=DEFAULT_CONFIGFILE)
    parser.add_argument(
        "--api",
        help=f"File with API Key (default is {DEFAULT_API_KEYFILE})",
        default=DEFAULT_API_KEYFILE)
    parser.add_argument(
        "--no-api",
        help="Skip validators that require making API requests",
        action='store_true')
    parser.add_argument(
        "--xml",
        help=
        "Process an XML file from 'Export Panorama configuration version'. This does not use an API key and implies --no-api"
    )
    parser.add_argument(
        "--debug",
        help="Write all debug output to pan_validator_debug_YYMMDD_HHMMSS.log",
        action='store_true')
    parser.add_argument(
        "--limit",
        help="Limit processing to the first N rules (useful for debugging)",
        type=int)
    parsed_args = parser.parse_args()

    configure_logging(parsed_args.debug, not parsed_args.quiet)
    logger.debug(
        f"Script launched with the following arguments {' '.join(sys.argv)}")
    if parsed_args.xml:
        api_key = ''
        parsed_args.no_api = True
        xml_string = "_xml"
    else:
        api_key = load_api_key(parsed_args.api)
        xml_string = ''

    if parsed_args.validator:
        validators = {
            validator: get_policy_validators()[validator]
            for validator in parsed_args.validator
        }
    else:
        validators = get_policy_validators()

    # Build the output string
    if parsed_args.device_group:
        devicegroup_string = "_" + parsed_args.device_group
    else:
        devicegroup_string = ''

    if parsed_args.validator:
        validators_string = "_" + "_".join(sorted(parsed_args.validator))
    else:
        validators_string = ''

    if parsed_args.limit:
        limit_string = "_limit" + str(parsed_args.limit)
    else:
        limit_string = ""

    if parsed_args.no_api:
        no_api_string = "_noapi"
    else:
        no_api_string = ""

    output_fname = f'pan_analyzer_output_{EXECUTION_START_TIME}{devicegroup_string}{xml_string}{no_api_string}{validators_string}{limit_string}.txt'
    logger.debug(f"Writing output to {output_fname}")

    no_api = parsed_args.no_api

    if not os.path.isfile(parsed_args.config):
        if parsed_args.config == DEFAULT_CONFIGFILE:
            ConfigurationSettings().write_config(parsed_args.config)
            logger.error(
                f"Config file '{parsed_args.config}' did not exist! Please edit the newly-created config and re-run."
            )
            sys.exit(1)
        else:
            raise Exception(
                f"Config file '{parsed_args.config}' does not exist! Exiting")
    configuration_settings = ConfigurationSettings(
        parsed_args.config).get_config()

    start_time = time.time()
    profilepackage = load_config_package(configuration_settings, api_key,
                                         parsed_args.device_group,
                                         parsed_args.limit, no_api,
                                         parsed_args.xml)
    problems, total_problems = run_policy_validators(validators,
                                                     profilepackage,
                                                     output_fname)
    write_validator_output(problems, output_fname, 'text')
    end_time = time.time()

    logger.info(f"Full run took {end_time - start_time} seconds")
    logger.info(f"Detected a total of {total_problems} problems")

    return
def main():
    description = """\
Fixes issues in PAN FW policies."""

    fixer_descriptions = '\n'.join(f"{readable_name} - {description}"
                                   for readable_name, description, f in sorted(
                                       get_policy_fixers().values()))
    epilog = f"""Here is a detailed list of the {len(get_policy_fixers().keys())} supported fixers:
{fixer_descriptions}
"""

    parser = argparse.ArgumentParser(
        description=description,
        epilog=epilog,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--all",
                       help="Run fixer on all Device Groups",
                       action='store_true')
    group.add_argument("--device-group",
                       help="Device Group to run through fixer")
    parser.add_argument("--fixer",
                        help="Fixer to run",
                        choices=sorted(get_policy_fixers().keys()),
                        required=True)
    parser.add_argument("--quiet", help="Silence output", action='store_true')
    parser.add_argument(
        "--config",
        help=f"Config file to read (default is {DEFAULT_CONFIGFILE})",
        default=DEFAULT_CONFIGFILE)
    parser.add_argument(
        "--api",
        help=f"File with API Key (default is {DEFAULT_API_KEYFILE})",
        default=DEFAULT_API_KEYFILE)
    parser.add_argument(
        "--debug",
        help="Write all debug output to pan_fixer_debug_YYMMDD_HHMMSS.log",
        action='store_true')
    parser.add_argument(
        "--limit",
        help="Limit processing to the first N rules (useful for debugging)",
        type=int)
    parsed_args = parser.parse_args()

    configure_logging(parsed_args.debug, not parsed_args.quiet)
    logger.debug(f"Execution began at {EXECUTION_START_TIME}")

    if not os.path.isfile(parsed_args.config):
        if parsed_args.config == DEFAULT_CONFIGFILE:
            ConfigurationSettings().write_config(parsed_args.config)
            logger.info(
                f"Config file '{parsed_args.config}' did not exist! Please edit the newly-created config and re-run."
            )
            sys.exit(1)
        else:
            raise Exception(
                f"Config file '{parsed_args.config}' does not exist! Exiting")
    configuration_settings = ConfigurationSettings(
        parsed_args.config).get_config()

    try:
        with open(parsed_args.api) as fh:
            API_KEY = fh.read().strip()
    except OSError:
        logger.info(f"Unable to open file with API key '{parsed_args.api}'")
        API_KEY = get_and_save_API_key(parsed_args.api)

    fixers = {parsed_args.fixer: get_policy_fixers()[parsed_args.fixer]}

    # Build the output string
    if parsed_args.device_group:
        devicegroup_string = "_" + parsed_args.device_group
    else:
        devicegroup_string = ''

    if parsed_args.fixer:
        fixers_string = "_" + parsed_args.fixer
    else:
        fixers_string = ''

    if parsed_args.limit:
        limit_string = "_limit" + str(parsed_args.limit)
    else:
        limit_string = ""

    output_fname = f'pan_fixer_output_{EXECUTION_START_TIME}{devicegroup_string}{fixers_string}{limit_string}.txt'

    start_time = time.time()
    profilepackage = load_config_package(configuration_settings, API_KEY,
                                         parsed_args.device_group,
                                         parsed_args.limit, True, False)
    problems, total_problems = run_policy_fixers(fixers, profilepackage,
                                                 output_fname)
    write_validator_output(problems, output_fname, 'text')
    end_time = time.time()

    logger.info("*" * 80)
    logger.info(f"Full run took {end_time - start_time} seconds")
    logger.info(f"Attempted to fix a total of {total_problems} problems")
    logger.info(f"Detected problems have been written to {output_fname}")

    return