def generate_example_dict(examples_file: Optional[str], insecure=False):
    """ Generate the example dict via an XSOAR server and return dict results.

    Args:
        examples_file: yaml as python dict.
        insecure: wether to run the examples without checking ssl.
    """
    command_examples = get_command_examples(examples_file, None)
    example_dict, build_errors = build_example_dict(command_examples, insecure)
    if build_errors:
        raise Exception(f'Command examples had errors: {build_errors}')
    return example_dict
def generate_integration_doc(input, output, examples, id_set, verbose=False):
    try:
        yml_data = get_yaml(input)

        errors = []
        example_dict = {}
        if examples and os.path.isfile(examples):
            command_examples = get_command_examples(examples)
            example_dict, build_errors = build_example_dict(command_examples)
            errors.extend(build_errors)
        else:
            errors.append(f'Command examples was not found {examples}.')

        docs = []  # type: list
        docs.extend(add_lines(yml_data.get('description')))
        docs.append(
            'This integration was integrated and tested with version xx of {}'.
            format(yml_data['name']))
        # Setup integration to work with Demisto
        docs.extend(
            generate_section(
                'Configure {} on Demisto'.format(yml_data['name']), ''))
        # Setup integration on Demisto
        docs.extend(generate_setup_section(yml_data))
        # Commands
        command_section, command_errors = generate_commands_section(
            yml_data, example_dict)
        docs.extend(command_section)
        errors.extend(command_errors)
        # Additional info
        docs.extend(generate_section('Additional Information', ''))
        # Known limitations
        docs.extend(generate_section('Known Limitations', ''))

        doc_text = '\n'.join(docs)

        save_output(output, 'README.md', doc_text)

        if errors:
            print_warning('Possible Errors:')
            for error in errors:
                print_warning(error)

    except Exception as ex:
        if verbose:
            raise
        else:
            print_error(f'Error: {str(ex)}')
            return
Ejemplo n.º 3
0
def generate_script_doc(input_path,
                        examples,
                        output: str = None,
                        permissions: str = None,
                        limitations: str = None,
                        insecure: bool = False,
                        verbose: bool = False):
    try:
        doc: list = []
        errors: list = []
        example_section: list = []

        if not output:  # default output dir will be the dir of the input file
            output = os.path.dirname(os.path.realpath(input_path))

        if examples:
            if os.path.isfile(examples):
                with open(examples, 'r') as examples_file:
                    examples = examples_file.read().splitlines()
            else:
                examples = examples.split(',')
                for i, example in enumerate(examples):
                    if not example.startswith('!'):
                        examples[i] = f'!{examples}'

            example_dict, build_errors = build_example_dict(examples, insecure)
            script_name = list(
                example_dict.keys())[0] if example_dict else None
            example_section, example_errors = generate_script_example(
                script_name, example_dict)
            errors.extend(build_errors)
            errors.extend(example_errors)
        else:
            errors.append(
                'Note: Script example was not provided. For a more complete documentation,run with the -e '
                'option with an example command. For example: -e "!ConvertFile entry_id=<entry_id>".'
            )

        script = get_yaml(input_path)

        # get script data
        script_info = get_script_info(input_path)
        script_id = script.get('commonfields')['id']

        # get script dependencies
        dependencies, _ = get_depends_on(script)

        # get the script usages by the id set
        if not os.path.isfile(DEFAULT_ID_SET_PATH):
            id_set_creator = IDSetCreator(output='', print_logs=False)
            id_set, _, _ = id_set_creator.create_id_set()
        else:
            id_set = open_id_set_file(DEFAULT_ID_SET_PATH)

        used_in = get_used_in(id_set, script_id)

        description = script.get('comment', '')
        # get inputs/outputs
        inputs, inputs_errors = get_inputs(script)
        outputs, outputs_errors = get_outputs(script)

        errors.extend(inputs_errors)
        errors.extend(outputs_errors)

        if not description:
            errors.append(
                'Error! You are missing a description for the Script')

        doc.append(description + '\n')

        doc.extend(generate_table_section(script_info, 'Script Data'))

        if dependencies:
            doc.extend(
                generate_list_section(
                    'Dependencies',
                    dependencies,
                    True,
                    text='This script uses the following commands and scripts.'
                ))

        # Script global permissions
        if permissions == 'general':
            doc.extend(generate_section('Permissions', ''))

        if used_in:
            if len(used_in) <= 10:
                doc.extend(
                    generate_list_section(
                        'Used In',
                        used_in,
                        True,
                        text=
                        'This script is used in the following playbooks and scripts.'
                    ))
            else:  # if we have more than 10 use a sample
                print_warning(
                    f'"Used In" section found too many scripts/playbooks ({len(used_in)}). Will use a sample of 10.'
                    ' Full list is available as a comment in the README file.')
                sample_used_in = random.sample(used_in, 10)
                doc.extend(
                    generate_list_section(
                        'Used In',
                        sorted(sample_used_in),
                        True,
                        text=
                        'Sample usage of this script can be found in the following playbooks and scripts.'
                    ))
                used_in_str = '\n'.join(used_in)
                doc.append(
                    f"<!--\nUsed In: list was truncated. Full list commented out for reference:\n\n{used_in_str}\n -->\n"
                )

        doc.extend(
            generate_table_section(inputs, 'Inputs',
                                   'There are no inputs for this script.'))

        doc.extend(
            generate_table_section(outputs, 'Outputs',
                                   'There are no outputs for this script.'))

        if example_section:
            doc.extend(example_section)

        # Known limitations
        if limitations:
            doc.extend(
                generate_numbered_section('Known Limitations', limitations))

        doc_text = '\n'.join(doc)

        save_output(output, 'README.md', doc_text)

        if errors:
            print_warning('Possible Errors:')
            for error in errors:
                print_warning(error)

    except Exception as ex:
        if verbose:
            raise
        else:
            print_error(f'Error: {str(ex)}')
            return
Ejemplo n.º 4
0
def generate_integration_doc(input_path: str,
                             examples: Optional[str] = None,
                             output: Optional[str] = None,
                             use_cases: Optional[str] = None,
                             permissions: Optional[str] = None,
                             command_permissions: Optional[str] = None,
                             limitations: Optional[str] = None,
                             insecure: bool = False,
                             verbose: bool = False,
                             command: Optional[str] = None):
    """ Generate integration documentation.

    Args:
        input_path: path to the yaml integration
        examples: path to the command examples
        output: path to the output documentation
        use_cases: use cases string
        permissions: global permissions for the docs
        command_permissions: permissions per command
        limitations: limitations description
        insecure: should use insecure
        verbose: verbose (debug mode)
        command: specific command to generate docs for

    """
    try:
        yml_data = get_yaml(input_path)

        if not output:  # default output dir will be the dir of the input file
            output = os.path.dirname(os.path.realpath(input_path))
        errors: list = []
        example_dict = {}
        if examples and os.path.isfile(examples):
            command_examples = get_command_examples(examples)
            example_dict, build_errors = build_example_dict(
                command_examples, insecure)
            errors.extend(build_errors)
        else:
            errors.append(f'Command examples was not found {examples}.')

        if permissions == 'per-command':
            command_permissions_dict: Any = {}
            if command_permissions and os.path.isfile(command_permissions):
                permission_list = get_command_permissions(command_permissions)
                for command_permission in permission_list:
                    # get all the permissions after the command name
                    key, value = command_permission.split(" ", 1)
                    command_permissions_dict.update({key: value})
            else:
                errors.append(
                    f'Command permissions was not found {command_permissions}.'
                )
        else:  # permissions in ['none', 'general']
            command_permissions_dict = None
        if command:
            specific_commands = command.split(',')
            readme_path = os.path.join(output, 'README.md')
            with open(readme_path) as f:
                doc_text = f.read()
            for specific_command in specific_commands:
                print(f'Generating docs for command `{command}`')
                command_section, command_errors = generate_commands_section(
                    yml_data,
                    example_dict,
                    command_permissions_dict,
                    command=specific_command)
                command_section_str = '\n'.join(command_section)
                doc_text, err = append_or_replace_command_in_docs(
                    doc_text, command_section_str, specific_command)
                errors.extend(err)
        else:
            docs = []  # type: list
            docs.extend(add_lines(yml_data.get('description')))
            docs.extend([
                'This integration was integrated and tested with version xx of {}'
                .format(yml_data['name'])
            ])
            # Integration use cases
            if use_cases:
                docs.extend(generate_numbered_section('Use Cases', use_cases))
            # Integration general permissions
            if permissions == 'general':
                docs.extend(generate_section('Permissions', ''))
            # Setup integration to work with Demisto
            docs.extend(
                generate_section(
                    'Configure {} on Cortex XSOAR'.format(yml_data['name']),
                    ''))
            # Setup integration on Demisto
            docs.extend(generate_setup_section(yml_data))
            # Commands
            command_section, command_errors = generate_commands_section(
                yml_data,
                example_dict,
                command_permissions_dict,
                command=command)
            docs.extend(command_section)
            errors.extend(command_errors)
            # Known limitations
            if limitations:
                docs.extend(
                    generate_numbered_section('Known Limitations',
                                              limitations))

            doc_text = '\n'.join(docs)

        save_output(output, 'README.md', doc_text)

        if errors:
            print_warning('Possible Errors:')
            for error in errors:
                print_warning(error)

    except Exception as ex:
        if verbose:
            raise
        else:
            print_error(f'Error: {str(ex)}')
            return
Ejemplo n.º 5
0
def generate_script_doc(input, output, examples, id_set='', verbose=False):
    try:
        doc = []
        errors = []
        used_in = []
        example_section = []

        if examples:
            if not examples.startswith('!'):
                examples = f'!{examples}'

            example_dict, build_errors = build_example_dict([examples])
            script_name = examples.split(' ')[0][1:]
            example_section, example_errors = generate_script_example(
                script_name, example_dict)
            errors.extend(build_errors)
            errors.extend(example_errors)
        else:
            errors.append(
                f'Note: Script example was not provided. For a more complete documentation,run with the -e '
                f'option with an example command. For example: -e "!ConvertFile entry_id=<entry_id>".'
            )

        script = get_yaml(input)

        # get script data
        secript_info = get_script_info(input)
        script_id = script.get('commonfields')['id']

        # get script dependencies
        dependencies, _ = get_depends_on(script)

        if not id_set:
            errors.append(f'id_set.json file is missing')
        elif not os.path.isfile(id_set):
            errors.append(f'id_set.json file {id_set} was not found')
        else:
            used_in = get_used_in(id_set, script_id)

        description = script.get('comment', '')
        deprecated = script.get('deprecated', False)
        # get inputs/outputs
        inputs, inputs_errors = get_inputs(script)
        outputs, outputs_errors = get_outputs(script)

        errors.extend(inputs_errors)
        errors.extend(outputs_errors)

        if not description:
            errors.append(
                'Error! You are missing description for the playbook')

        if deprecated:
            doc.append('`Deprecated`')

        doc.append(description)

        doc.extend(generate_table_section(secript_info, 'Script Data'))

        if dependencies:
            doc.extend(
                generate_list_section(
                    'Dependencies',
                    dependencies,
                    True,
                    text='This script uses the following commands and scripts.'
                ))

        if used_in:
            doc.extend(
                generate_list_section(
                    'Used In',
                    used_in,
                    True,
                    text=
                    'This script is used in the following playbooks and scripts.'
                ))

        doc.extend(
            generate_table_section(inputs, 'Inputs',
                                   'There are no inputs for this script.'))

        doc.extend(
            generate_table_section(outputs, 'Outputs',
                                   'There are no outputs for this script.'))

        if example_section:
            doc.extend(example_section)

        doc_text = '\n'.join(doc)

        save_output(output, 'README.md', doc_text)

        if errors:
            print_warning('Possible Errors:')
            for error in errors:
                print_warning(error)

    except Exception as ex:
        if verbose:
            raise
        else:
            print_error(f'Error: {str(ex)}')
            return
def generate_integration_doc(input, examples, output: str = None, use_cases: str = None,
                             permissions: str = None, command_permissions: str = None,
                             limitations: str = None, insecure: bool = False, verbose: bool = False):
    try:
        yml_data = get_yaml(input)

        if not output:  # default output dir will be the dir of the input file
            output = os.path.dirname(os.path.realpath(input))

        errors = []
        example_dict = {}
        if examples and os.path.isfile(examples):
            command_examples = get_command_examples(examples)
            example_dict, build_errors = build_example_dict(command_examples, insecure)
            errors.extend(build_errors)
        else:
            errors.append(f'Command examples was not found {examples}.')

        if permissions == 'per-command':
            command_permissions_dict = {}
            if command_permissions and os.path.isfile(command_permissions):
                command_permissions = get_command_permissions(command_permissions)
                for command_permission in command_permissions:
                    # get all the permissions after the command name
                    key, value = command_permission.split(" ", 1)
                    command_permissions_dict.update({key: value})
            else:
                errors.append(f'Command permissions was not found {command_permissions}.')
        else:  # permissions in ['none', 'general']
            command_permissions_dict = None

        docs = []  # type: list
        docs.extend(add_lines(yml_data.get('description')))
        docs.extend(['This integration was integrated and tested with version xx of {}'.format(yml_data['name'])])

        # Integration use cases
        if use_cases:
            docs.extend(generate_numbered_section('Use Cases', use_cases))
        # Integration general permissions
        if permissions == 'general':
            docs.extend(generate_section('Permissions', ''))
        # Setup integration to work with Demisto
        docs.extend(generate_section('Configure {} on Demisto'.format(yml_data['name']), ''))
        # Setup integration on Demisto
        docs.extend(generate_setup_section(yml_data))
        # Commands
        command_section, command_errors = generate_commands_section(yml_data, example_dict, command_permissions_dict)
        docs.extend(command_section)
        errors.extend(command_errors)
        # Known limitations
        if limitations:
            docs.extend(generate_numbered_section('Known Limitations', limitations))

        doc_text = '\n'.join(docs)

        save_output(output, 'README.md', doc_text)

        if errors:
            print_warning('Possible Errors:')
            for error in errors:
                print_warning(error)

    except Exception as ex:
        if verbose:
            raise
        else:
            print_error(f'Error: {str(ex)}')
            return
def generate_script_doc(input,
                        examples,
                        output: str = None,
                        permissions: str = None,
                        limitations: str = None,
                        insecure: bool = False,
                        verbose: bool = False):
    try:
        doc = []
        errors = []
        used_in = []
        example_section = []

        if not output:  # default output dir will be the dir of the input file
            output = os.path.dirname(os.path.realpath(input))

        if examples:
            if not examples.startswith('!'):
                examples = f'!{examples}'

            example_dict, build_errors = build_example_dict([examples],
                                                            insecure)
            script_name = examples.split(' ')[0][1:]
            example_section, example_errors = generate_script_example(
                script_name, example_dict)
            errors.extend(build_errors)
            errors.extend(example_errors)
        else:
            errors.append(
                f'Note: Script example was not provided. For a more complete documentation,run with the -e '
                f'option with an example command. For example: -e "!ConvertFile entry_id=<entry_id>".'
            )

        script = get_yaml(input)

        # get script data
        secript_info = get_script_info(input)
        script_id = script.get('commonfields')['id']

        # get script dependencies
        dependencies, _ = get_depends_on(script)

        # get the script usages by the id set
        id_set_creator = IDSetCreator()
        id_set = id_set_creator.create_id_set()
        used_in = get_used_in(id_set, script_id)

        description = script.get('comment', '')
        deprecated = script.get('deprecated', False)
        # get inputs/outputs
        inputs, inputs_errors = get_inputs(script)
        outputs, outputs_errors = get_outputs(script)

        errors.extend(inputs_errors)
        errors.extend(outputs_errors)

        if not description:
            errors.append(
                'Error! You are missing description for the playbook')

        if deprecated:
            doc.append('`Deprecated`')

        doc.append(description)

        doc.extend(generate_table_section(secript_info, 'Script Data'))

        if dependencies:
            doc.extend(
                generate_list_section(
                    'Dependencies',
                    dependencies,
                    True,
                    text='This script uses the following commands and scripts.'
                ))

        # Script global permissions
        if permissions == 'general':
            doc.extend(generate_section('Permissions', ''))

        if used_in:
            doc.extend(
                generate_list_section(
                    'Used In',
                    used_in,
                    True,
                    text=
                    'This script is used in the following playbooks and scripts.'
                ))

        doc.extend(
            generate_table_section(inputs, 'Inputs',
                                   'There are no inputs for this script.'))

        doc.extend(
            generate_table_section(outputs, 'Outputs',
                                   'There are no outputs for this script.'))

        if example_section:
            doc.extend(example_section)

        # Known limitations
        if limitations:
            doc.extend(
                generate_numbered_section('Known Limitations', limitations))

        doc_text = '\n'.join(doc)

        save_output(output, 'README.md', doc_text)

        if errors:
            print_warning('Possible Errors:')
            for error in errors:
                print_warning(error)

    except Exception as ex:
        if verbose:
            raise
        else:
            print_error(f'Error: {str(ex)}')
            return
def generate_integration_doc(input_path: str,
                             examples: Optional[str] = None,
                             output: Optional[str] = None,
                             use_cases: Optional[str] = None,
                             permissions: Optional[str] = None,
                             command_permissions: Optional[str] = None,
                             limitations: Optional[str] = None,
                             insecure: bool = False,
                             verbose: bool = False,
                             command: Optional[str] = None,
                             old_version: str = '',
                             skip_breaking_changes: bool = False,
                             is_contribution: bool = False):
    """ Generate integration documentation.

    Args:
        input_path: path to the yaml integration
        examples: path to the command examples
        output: path to the output documentation
        use_cases: use cases string
        permissions: global permissions for the docs
        command_permissions: permissions per command
        limitations: limitations description
        insecure: should use insecure
        verbose: verbose (debug mode)
        command: specific command to generate docs for
        is_contribution: Check if the content item is a new integration contribution or not.

    """
    try:
        yml_data = get_yaml(input_path)

        if not output:  # default output dir will be the dir of the input file
            output = os.path.dirname(os.path.realpath(input_path))
        errors: list = []
        example_dict: dict = {}
        if examples:
            specific_commands = command.split(',') if command else None
            command_examples = get_command_examples(examples,
                                                    specific_commands)
            example_dict, build_errors = build_example_dict(
                command_examples, insecure)
            errors.extend(build_errors)
        else:
            errors.append(f'Command examples was not found: {examples}.')

        if permissions == 'per-command':
            command_permissions_dict: Any = {}
            if command_permissions and os.path.isfile(command_permissions):
                permission_list = get_command_permissions(command_permissions)
                for command_permission in permission_list:
                    # get all the permissions after the command name
                    key, value = command_permission.split(" ", 1)
                    command_permissions_dict.update({key: value})
            else:
                errors.append(
                    f'Command permissions was not found {command_permissions}.'
                )
        else:  # permissions in ['none', 'general']
            command_permissions_dict = None
        if command:
            specific_commands = command.split(',')
            readme_path = os.path.join(output, 'README.md')
            with open(readme_path) as f:
                doc_text = f.read()
            for specific_command in specific_commands:
                print(f'Generating docs for command `{specific_command}`')
                command_section, command_errors = generate_commands_section(
                    yml_data,
                    example_dict,
                    command_permissions_dict,
                    command=specific_command)
                command_section_str = '\n'.join(command_section)
                doc_text, err = append_or_replace_command_in_docs(
                    doc_text, command_section_str, specific_command)
                errors.extend(err)
        else:
            docs = []  # type: list
            docs.extend(add_lines(yml_data.get('description')))
            if not is_contribution:
                docs.extend([
                    'This integration was integrated and tested with version xx of {}'
                    .format(yml_data['name']), ''
                ])
            # Checks if the integration is a new version
            integration_version = re.findall("[vV][2-9]$",
                                             yml_data.get("display", ""))
            if integration_version and not skip_breaking_changes:
                docs.extend([
                    'Some changes have been made that might affect your existing content. '
                    '\nIf you are upgrading from a previous of this integration, see [Breaking Changes]'
                    '(#breaking-changes-from-the-previous-version-of-this-integration-'
                    f'{yml_data.get("display", "").replace(" ", "-").lower()}).',
                    ''
                ])
            # Integration use cases
            if use_cases:
                docs.extend(generate_numbered_section('Use Cases', use_cases))
            # Integration general permissions
            if permissions == 'general':
                docs.extend(generate_section('Permissions', ''))
            # Setup integration to work with Demisto
            docs.extend(
                generate_section(
                    'Configure {} on Cortex XSOAR'.format(yml_data['display']),
                    ''))
            # Setup integration on Demisto
            docs.extend(generate_setup_section(yml_data))
            # Commands
            command_section, command_errors = generate_commands_section(
                yml_data,
                example_dict,
                command_permissions_dict,
                command=command)
            docs.extend(command_section)
            # breaking changes
            if integration_version and not skip_breaking_changes:
                docs.extend(
                    generate_versions_differences_section(
                        input_path, old_version, yml_data.get("display", "")))

            errors.extend(command_errors)
            # Known limitations
            if limitations:
                docs.extend(
                    generate_numbered_section('Known Limitations',
                                              limitations))

            doc_text = '\n'.join(docs)

        save_output(output, 'README.md', doc_text)

        if errors:
            print_warning('Possible Errors:')
            for error in errors:
                print_warning(error)

    except Exception as ex:
        if verbose:
            raise
        else:
            print_error(f'Error: {str(ex)}')
            return