import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import yaml from CommonServerUserPython import * CMD_ARGS_REGEX = re.compile(r'([\w_-]+)=((?:\"[^"]+\")|(?:`.+`)|(?:\"\"\".+\"\"\")|(?:[^ ]+)) ?', re.S) """STRING TEMPLATES""" OVERVIEW: str = '''
{overview}
''' SETUP_CONFIGURATION: str = '''You can execute these commands from the Demisto CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.
The following permissions are required for all commands.
The following permissions are required for this command.
{command_description}
{command}
{command_example}
{hr_example}
''' CONTEXT_EXAMPLE: str = '''
{context}
'''
ARG_TABLE: str = '''| Argument Name | Description | Required |
|---|
| Path | Type | Description |
|---|
\n{}\n
'.format('\n'.join(paragraph))) return '\n'.join(hr_html) def generate_use_case_section(title, data): html_section = [ '{}
'.format(data)) return html_section def generate_section(title, data): html_section = [ '{}
\n'.format(data)) return '\n'.join(html_section) # Setup integration on Demisto def generate_setup_section(yaml_data): params_list = [ PARAMS_LIST.format(param=conf['display'] if conf.get('display') else conf['name']) for conf in yaml_data.get('configuration', [])] return SETUP_CONFIGURATION.format(params_list='\n'.join(params_list), integration_name=yaml_data['name']) # Commands def generate_commands_section(yaml_data, example_dict, should_include_permissions): errors: list = [] command_sections: list = [] commands = [cmd for cmd in yaml_data['script']['commands'] if not cmd.get('deprecated')] command_list = [COMMAND_LIST.format(command_hr=cmd['description'].rstrip('.'), command=cmd['name']) for cmd in commands] for i, cmd in enumerate(commands): cmd_section, cmd_errors = generate_single_command_section(i + 1, cmd, example_dict, should_include_permissions) command_sections.append(cmd_section) errors.extend(cmd_errors) return (COMMANDS_HEADER.format(command_list='\n'.join(command_list)) + '\n'.join(command_sections)), errors def generate_single_command_section(index, cmd, example_dict, should_include_permissions): cmd_example: str = example_dict.get(cmd['name']) errors: list = [] template: dict = { 'index': index, 'command_hr': cmd['name'], 'command': cmd['name'], 'command_description': cmd.get('description', ' '), 'permissions': PERMISSIONS_PER_COMMAND if should_include_permissions else '', } # Inputs arguments: list = cmd.get('arguments') if arguments is None: template['arg_table'] = 'There are no input arguments for this command.' else: arg_table: list = [] for arg in arguments: if not arg.get('description'): errors.append( 'Error! You are missing description in input {} of command {}'.format(arg['name'], cmd['name'])) required_status = 'Required' if arg.get('required') else 'Optional' arg_table.append(ARG_RECORD.format(name=arg['name'], description=arg.get('description'), required=required_status)) template['arg_table'] = ARG_TABLE.format(records='\n'.join(arg_table)) # Context output outputs: list = cmd.get('outputs') if outputs is None: template['context_table'] = 'There are no context output for this command.' else: context_table: list = [] for output in outputs: if not output.get('description'): errors.append( 'Error! You are missing description in output {} of command {}'.format(output['contextPath'], cmd['name'])) context_table.append(CONTEXT_RECORD.format(path=output['contextPath'], type=output.get('type', 'unknown'), description=output.get('description'))) template['context_table'] = CONTEXT_TABLE.format(records='\n'.join(context_table)) # Raw output: example_template, example_errors = generate_command_example(cmd, cmd_example) template.update(example_template) errors.extend(example_errors) return SINGLE_COMMAND.format(**template), errors def generate_command_example(cmd, cmd_example=None): errors: list = [] context_example = None md_example: str = '' if cmd_example: cmd_example, md_example, context_example = cmd_example else: cmd_example = ' ' errors.append('did not get any example for {}. please add it manually.'.format(cmd['name'])) example = { 'command_example': cmd_example, 'hr_example': human_readable_example_to_html(md_example), 'context_example': CONTEXT_EXAMPLE.format(context=context_example) if context_example else '', } return example, errors def generate_html_docs(args, yml_data, example_dict, errors): docs: str = '' # Overview overview = (args.get('overview', yml_data.get('description')) + '\n\nThis integration was integrated and tested with version xx of {}'.format(yml_data['name'])) docs += OVERVIEW.format(overview=overview) # Playbooks docs += generate_section('{} Playbook'.format(yml_data['name']), 'Populate this section with relevant playbook names.') # Use Cases docs += generate_section('Use Cases', args.get('useCases', 'Use case 1\nUse case 2')) # Detailed Descriptions docs += generate_section('Detailed Description', yml_data.get('detaileddescription', 'Populate this section with the .md file contents for detailed description.')) # Fetch Data docs += generate_section('Fetch Incidents', args.get('fetchedData', 'Populate this section with Fetch incidents data')) # # Setup integration to work with Demisto # docs.extend(generate_section('Configure {} on Demisto'.format(yml_data['name']), args.get('setupOnIntegration'))) # Setup integration on Demisto docs += (generate_setup_section(yml_data)) # Permissions if args.get('permissions') == 'global': docs += PERMISSIONS_HEADER # Commands command_section, command_errors = generate_commands_section(yml_data, example_dict, args.get('permissions') == 'per-command') docs += command_section errors.extend(command_errors) # Additional info docs += generate_section('Additional Information', args.get('addInfo')) # Known limitations docs += generate_section('Known Limitations', args.get('limit')) # Troubleshooting docs += generate_section('Troubleshooting', args.get('troubleshooting')) return docs def main(): args: dict = demisto.args() yml_data: dict = get_yaml_obj(args.get('entryID')) command_examples, errors = get_command_examples(args.get('commands')) example_dict, build_errors = build_example_dict(command_examples) errors.extend(build_errors) docs: str = generate_html_docs(args, yml_data, example_dict, errors) filename = '{}-documentation.html'.format(yml_data['name']) demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['html'], 'Contents': docs, # 'HumanReadable': docs, }) demisto.results(fileResult(filename, docs, file_type=entryTypes['entryInfoFile'])) if errors: errors.append('Visit the documentation page for more details: ' 'https://github.com/demisto/content/tree/master/docs/integration_documentation') return_error('\n'.join('* {}'.format(e) for e in errors)) if __name__ == 'builtins': main()