class ServiceDeskHelper
Attributes
log[RW]
Public Class Methods
new(service_data, options, mode)
click to toggle source
Calls superclass method
BaseHelper::new
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 11 def initialize(service_data, options, mode) super(service_data, options, mode) @rest_uri = service_data[:rest_uri] @api_key = service_data[:api_key] @ticket_db_path = service_data[:ticket_db_path] end
Public Instance Methods
add_ticket_to_database(workorderid, nxid)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 25 def add_ticket_to_database(workorderid, nxid) @log.log_message("Adding ticket <#{workorderid}> for NXID <#{nxid}> to local db.") db = open_database() db[nxid] = workorderid db.close() end
close_ticket(ticket)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 257 def close_ticket(ticket) @log.log_message("Connecting to #{@rest_uri}/#{ticket[:workorderid]}") uri = URI( "#{@rest_uri}/#{ticket[:workorderid]}" ) res = Net::HTTP::post_form(uri, 'OPERATION_NAME' => 'CLOSE_REQUEST', 'TECHNICIAN_KEY' => @api_key) response = Nokogiri::XML.parse(res.read_body) begin status = Integer(response.xpath('//statuscode').text) rescue Exception => e @log.log_message("XML request was #{ticket[:description]} response is #{response.to_xml}") raise e end unless status == 200 @log.log_message("Unable to close ticket #{ticket}, got response #{response.to_xml}") end end
close_tickets( tickets )
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 334 def close_tickets( tickets ) to_close = tickets.select { |t| t[:action] == :close && !t[:workorderid].nil? } @metrics.closed to_close.count to_close.each { |ticket| close_ticket(ticket) } remove_tickets_from_database(tickets) end
create_ticket_request(subject, description)
click to toggle source
Uses the configured or default options to set up a ticket creation request
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 128 def create_ticket_request(subject, description) request = Nokogiri::XML::Builder.new do |xml| xml.Operation { xml.Details { xml.parameter { xml.name { xml.text 'requester' } xml.value { xml.text @service_data[:requester] } } xml.parameter { xml.name { xml.text 'Group' } xml.value { xml.text @service_data[:group] } } xml.parameter { xml.name { xml.text 'subject' } xml.value { xml.text subject } } xml.parameter { xml.name { xml.text 'description' } xml.value { xml.cdata description } } } } end request.to_xml end
create_tickets(tickets)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 278 def create_tickets(tickets) @log.log_message("Creating tickets on server at #{@rest_uri}") tickets.each { |ticket| submit_ticket(ticket) } end
find_ticket_in_database(nxid)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 33 def find_ticket_in_database(nxid) @log.log_message("Finding workorder id for NXID <#{nxid}> from local db.") db = open_database() begin workorderid = db[nxid] @log.log_message("Lookup found incident <#{workorderid}> in the db.") rescue Exception => e @log.log_message("Threw an exception accessing the dbm <#{e.class} #{e} #{e.message}>.") raise e end db.close() workorderid end
modify_ticket(ticket)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 235 def modify_ticket(ticket) @log.log_message("Connecting to #{@rest_uri}/#{ticket[:workorderid]}") uri = URI( "#{@rest_uri}/#{ticket[:workorderid]}") res = Net::HTTP::post_form(uri, 'OPERATION_NAME' => 'EDIT_REQUEST', 'TECHNICIAN_KEY' => @api_key, 'INPUT_DATA' => ticket[:description]) response = Nokogiri::XML.parse(res.read_body) begin status = Integer(response.xpath('//statuscode').text) rescue Exception => e @log.log_message("XML request was #{ticket[:description]} response is #{response.to_xml}") raise e end unless status == 200 @log.log_message("Unable to modify ticket #{ticket}, got response #{response.to_xml}") end end
modify_ticket_request(description)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 170 def modify_ticket_request(description) # modifyRequest = """ # <Operation> # <Details> # <parameter> # <name>description</name> # <value>#{description}</value> # </parameter> # </Details> # </Operation> # """ doc = Nokogiri::XML::Builder.new() do |xml| xml.Operation { xml.Details { xml.parameter { xml.name { xml.text 'requester' } xml.value { xml.text @service_data[:requester] } } xml.parameter { xml.name { xml.text 'description' } xml.value { xml.cdata description } } } } end doc.to_xml end
open_database()
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 20 def open_database() DBM.open(@ticket_db_path, 0600, DBM::WRCREAT) end
prepare_close_tickets(vulnerability_list, nexpose_identifier_id)
click to toggle source
Prepare ticket closures from the CSV of vulnerabilities exported from Nexpose.
-
Args :
-
vulnerability_list
- CSV of vulnerabilities within Nexpose.
-
-
Returns :
-
List of savon-formated (hash) tickets for closing within ServiceDesk.
-
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 312 def prepare_close_tickets(vulnerability_list, nexpose_identifier_id) @log.log_message("Preparing ticket closures for mode #{@options[:ticket_mode]}.") @nxid = nil tickets = [] CSV.parse(vulnerability_list.chomp, headers: :first_row) do |row| @nxid = @mode_helper.get_nxid(nexpose_identifier_id, row) workorderid = find_ticket_in_database(@nxid) # Query ServiceDesk for the incident by unique id (generated NXID) if workorderid.nil? || workorderid.empty? @log.log_message("No workorderid found for NXID #{@nxid}") else tickets << { :action => :close, :nxid => @nxid, :workorderid => workorderid, :description => 'Automatically closing ticket.' } end end tickets end
prepare_create_tickets(vulnerability_list, nexpose_identifier_id)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 60 def prepare_create_tickets(vulnerability_list, nexpose_identifier_id) @log.log_message('Preparing ticket creation...') tickets = prepare_tickets(vulnerability_list, nexpose_identifier_id) tickets.each { |ticket| @log.log_message("Prepared ticket: #{ticket}")} tickets end
prepare_tickets(vulnerability_list, nexpose_identifier_id)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 69 def prepare_tickets(vulnerability_list, nexpose_identifier_id) @metrics.start @log.log_message("Preparing ticket for #{@options[:ticket_mode]} mode.") matching_fields = @mode_helper.get_matching_fields tickets = [] host_vulns={} previous_row = nil description = nil nxid = nil initial_scan = false CSV.parse( vulnerability_list.chomp, headers: :first_row ) do |row| initial_scan = initial_scan || row['comparison'].nil? if previous_row.nil? nxid = @mode_helper.get_nxid(nexpose_identifier_id, row) previous_row = row.dup description = @mode_helper.get_description(nexpose_identifier_id, row) host_vulns[nxid] = { :ip => row['ip_address'], :description => "", :title => @mode_helper.get_title(row) } elsif matching_fields.any? { |x| previous_row[x].nil? || previous_row[x] != row[x] } info = @mode_helper.get_field_info(matching_fields, previous_row) @log.log_message("Generated ticket with #{info}") host_vulns[nxid][:description] = @mode_helper.print_description(description) previous_row = nil description = nil redo else description = @mode_helper.update_description(description, row) end end unless host_vulns[nxid].nil? || host_vulns[nxid].empty? host_vulns[nxid][:description] = @mode_helper.print_description(description) end host_vulns.each do |nxid, vuln_info| workorderid = initial_scan ? nil : find_ticket_in_database(nxid) if workorderid.nil? || workorderid.empty? @log.log_message("Creating new incident for assetid #{nxid}") @metrics.created tickets << { :action => :create, :nxid => nxid, :description => create_ticket_request(vuln_info[:title], vuln_info[:description]) } else @log.log_message("Updating incident for assetid #{nxid}") @metrics.updated tickets << { :action => :modify, :nxid => nxid, :workorderid => workorderid, :description => modify_ticket_request(vuln_info[:description]) } end end tickets end
prepare_update_tickets(vulnerability_list, nexpose_identifier_id)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 285 def prepare_update_tickets(vulnerability_list, nexpose_identifier_id) @log.log_message('Preparing ticket updates...') prepare_tickets(vulnerability_list, nexpose_identifier_id) end
remove_tickets_from_database(tickets)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 49 def remove_tickets_from_database(tickets) db = open_database() tickets.each do |t| nxid = t[:nxid] @log.log_message("Removing workorder id from database for NXID <#{nxid}>") db.delete(nxid) unless db[nxid].nil? end db.close() end
submit_ticket(ticket)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 206 def submit_ticket(ticket) @log.log_message("Connecting to #{@rest_uri}.") uri = URI( @rest_uri ) res = Net::HTTP::post_form(uri, 'OPERATION_NAME' => 'ADD_REQUEST', 'TECHNICIAN_KEY' => @api_key, 'INPUT_DATA' => ticket[:description]) response = Nokogiri::XML.parse(res.read_body) begin status = response.xpath('//statuscode').text status_code = status.empty? ? -1 : Integer(status) if status_code != 200 @log.log_message("Unable to create ticket #{ticket}, got response #{response.to_xml}") return end workorderid = Integer(response.xpath('//workorderid').text) rescue ArgumentError => ae @log.log_message("Failed to parse response from servicedesk #{response}") raise ae end @log.log_message( "created ticket #{workorderid}") add_ticket_to_database( workorderid, ticket[:nxid] ) end
update_tickets(tickets)
click to toggle source
# File lib/nexpose_ticketing/helpers/servicedesk_helper.rb, line 291 def update_tickets(tickets) @log.log_message('Updating tickets') tickets.each do |ticket| if ticket[:action] == :create @log.log_message('Creating ticket') submit_ticket(ticket) else @log.log_message("Updating ticket #{ticket[:workorderid]}") modify_ticket(ticket) end end end