def add_non_finding(issue, options): """ Adds a non-finding. """ title = validate_report.capitalize(issue.title.strip()) print_status('{0} - {1} - {2}'.format(issue.state, issue.labels, title), options) non_finding_id = '{0}-{1}'.format(issue.iid, valid_filename(title)) filename = 'non-findings/{0}.xml'.format(non_finding_id) non_finding = collections.OrderedDict() non_finding['title'] = title non_finding['p'] = unicode.replace(issue.description, '\r\n', '\n') for note in [x for x in issue.notes.list() if not x.system]: non_finding['p'] += unicode.replace(note.body, '\r\n', '\n') non_finding_xml = jxmlease.XMLDictNode(non_finding, tag='non-finding', xml_attrs={'id': non_finding_id}) if options['dry_run']: print_line('[+] {0}'.format(filename)) print(non_finding_xml.emit_xml()) else: if os.path.isfile(filename) and not options['overwrite']: print_line( 'Non-finding {0} already exists (use --overwrite to overwrite)' .format(filename)) else: if options['y'] or ask_permission('Create file ' + filename): with open(filename, 'w') as xmlfile: xmlfile.write(non_finding_xml.emit_xml().encode('utf-8')) print_line('[+] Created {0}'.format(filename))
def load_merge_xml_config(device, user, pw, config): """Load a configuration using "configure private" and "load merge". Given a configuration snippet as a jxmlease.XMLDictNode, do: configure private, load merge of the config snippet, commit (and close the configuration), and check the results. Return True if the config was committed successfully, False otherwise. """ load_config_node = jxmlease.XMLDictNode(config, tag='load-configuration') load_config_node.set_xml_attr('action', 'merge') load_config_node.set_xml_attr('format', 'xml') rpcs = [] rpcs.append({'open-configuration': {'private': ''}}) rpcs.append(load_config_node) rpcs.append({'commit-configuration': ''}) rpcs.append({'close-configuration': ''}) payload_string = jxmlease.XMLListNode(rpcs).emit_xml(full_document=False) args = {'stop-on-error': '1'} headers = {'Accept': 'application/xml', 'Content-Type': 'application/xml'} url = MULTIPLE_RPC_URL_FORMAT % (device) http_resp = requests.post(url, auth=(user, pw), params=args, headers=headers, data=payload_string) http_resp.raise_for_status() responses = parse_multipart_messages( type=http_resp.headers['Content-Type'], response=http_resp.text) rc = True if len(responses) != len(rpcs): print " Error: Fewer responses than expected!" rc = False for xml_response in responses: if xml_response == None: print " Error: Unable to parse an RPC response!" rc = False else: (error_count, warning_count) = check_for_warnings_and_errors( parser(xml_response)) if error_count > 0: rc = False return rc
def get_xml_request(module, request, xmlns, content): if content is None: if xmlns is None: return "<%s/>" % request else: return '<%s xmlns="%s"/>' % (request, xmlns) if isinstance(content, str): content = content.strip() if content.startswith("<") and content.endswith(">"): # assumption content contains already XML payload if xmlns is None: return "<%s>%s</%s>" % (request, content, request) else: return '<%s xmlns="%s">%s</%s>' % ( request, xmlns, content, request, ) try: # trying if content contains dict content = ast.literal_eval(content) except Exception: module.fail_json(msg="unsupported content value `%s`" % content) if isinstance(content, dict): if not HAS_JXMLEASE: module.fail_json( msg="jxmlease is required to convert RPC content to XML " "but does not appear to be installed. " "It can be installed using `pip install jxmlease`" ) payload = jxmlease.XMLDictNode(content).emit_xml( pretty=False, full_document=False ) if xmlns is None: return "<%s>%s</%s>" % (request, payload, request) else: return '<%s xmlns="%s">%s</%s>' % ( request, xmlns, payload, request, ) module.fail_json( msg="unsupported content data-type `%s`" % type(content).__name__ )
def build_config_changes(desc_changes): """Generate a configuration snippet with new interface descriptions. Given a dictionary of new description values to be configured, build a configuration snippet as a jxmlease.XMLDictNode. The configuration snippet will configure the new description for each interface. Return the configuration snippet as a jxmlease.XMLDictNode. """ interface_list = [] for local_port in desc_changes: interface_list.append({ 'name': local_port, 'description': desc_changes[local_port] }) config = {'configuration': {'interfaces': {'interface': interface_list}}} return jxmlease.XMLDictNode(config)
def add_finding(issue, options): """ Writes issue as XML finding to file. """ title = validate_report.capitalize(issue.title.strip()) print_status('{0} - {1} - {2}'.format(issue.state, issue.labels, title), options) threat_level = 'Moderate' finding_type = 'TODO' finding_id = '{0}-{1}'.format(issue.iid, valid_filename(title)) filename = 'findings/{0}.xml'.format(finding_id) finding = collections.OrderedDict() finding['title'] = title finding['description'] = unicode.replace(issue.description, '\r\n', '\n') finding['technicaldescription'] = '' for note in [x for x in issue.notes.list() if not x.system]: finding['technicaldescription'] += unicode.replace( note.body, '\r\n', '\n') finding['impact'] = {} finding['impact']['p'] = 'TODO' finding['recommendation'] = {} finding['recommendation']['ul'] = {} finding['recommendation']['ul']['li'] = 'TODO' finding_xml = jxmlease.XMLDictNode(finding, tag='finding', xml_attrs={ 'id': finding_id, 'threatLevel': threat_level, 'type': finding_type }) if options['dry_run']: print_line('[+] {0}'.format(filename)) print(finding_xml.emit_xml()) else: if os.path.isfile(filename) and not options['overwrite']: print_line( 'Finding {0} already exists (use --overwrite to overwrite)'. format(filename)) else: if options['y'] or ask_permission('Create file ' + filename): with open(filename, 'w') as xmlfile: xmlfile.write(finding_xml.emit_xml().encode('utf-8')) print_line('[+] Created {0}'.format(filename))