class TenableRuby::Client
Attributes
Public Class Methods
initialize object: try to connect to tenable.io Usage:
TenableRuby::Client.new (:credentials => {username: 'user', password: 'password'}) or TenableRuby::Client.new (:credentials => {access_key: 'XXX', secret_key: 'XXX'})
# File lib/tenable-ruby.rb, line 56 def initialize(params = {}) # defaults @tenable_url = params.fetch(:url, 'https://cloud.tenable.com') @credentials = params.fetch(:credentials) @ssl_verify = params.fetch(:ssl_verify, false) @ssl_use = params.fetch(:ssl_use, true) @autologin = params.fetch(:autologin, true) @defsleep = params.fetch(:defsleep, 1) @httpretry = params.fetch(:httpretry, 1) @httpsleep = params.fetch(:httpsleep, 1) init_quick_defaults uri = URI.parse(@tenable_url) @connection = Net::HTTP.new(uri.host, uri.port) @connection.use_ssl = @ssl_use if @ssl_verify @connection.verify_mode = OpenSSL::SSL::VERIFY_PEER else @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE end yield @connection if block_given? authenticate if @autologin end
Public Instance Methods
Creates a bulk operation task to unlink agents
Reference developer.tenable.com/reference#bulk-unlink-agents
# File lib/tenable-ruby.rb, line 322 def agent_bulk_unlink(scanner_id, agent_ids) http_post( :uri => "/scanners/#{scanner_id}/agents/_bulk/unlink", :fields => header, :body => { :items => agent_ids }.to_json, :ctype => 'application/json', ) end
Adds an agent to the agent group
Reference developer.tenable.com/reference#agent-groups-add-agent
# File lib/tenable-ruby.rb, line 295 def agent_group_add_agent(scanner_id, group_id, agent_id) payload = { :scanner_id => scanner_id, :group_id => group_id, :agent_id => agent_id, }.to_json options = { :uri => "/scanners/#{scanner_id}/agent-groups/#{group_id}/agents/#{agent_id}", :body => payload, :fields => header, :ctype => 'application/json', } http_put(options) end
Creates an agent group on the scanner
Reference developer.tenable.com/reference#agent-groups-create
# File lib/tenable-ruby.rb, line 269 def agent_group_create(scanner_id, name) payload = { :scanner_id => scanner_id, :name => name, }.to_json options = { :uri => "/scanners/#{scanner_id}/agent-groups", :body => payload, :fields => header, :ctype => 'application/json', } http_post(options) end
Deletes an agent group on the scanner
Reference developer.tenable.com/reference#agent-groups-delete
# File lib/tenable-ruby.rb, line 287 def agent_group_delete(scanner_id, group_id) http_delete(:uri => "/scanners/#{scanner_id}/agent-groups/#{group_id}", :fields => header) end
Returns a list of agent groups for the specified scanner
Reference developer.tenable.com/reference#agent-groups-list
# File lib/tenable-ruby.rb, line 260 def agent_group_list(scanner_id) url = "/scanners/#{scanner_id}/agent-groups" http_get(:uri => url, :fields => header) end
Returns a list of agents for the specified scanner
Reference developer.tenable.com/reference#agents-list
# File lib/tenable-ruby.rb, line 247 def agent_list(params=nil) url = "/scanners/scanner_list/agents" unless params.nil? params = params.to_a.map { |x| "#{x[0]}=#{x[1]}" }.join("&") url = "#{url}?#{params}" end http_get(:uri => url, :fields => header) end
Unlinks an agent
Reference developer.tenable.com/reference#agents-delete
# File lib/tenable-ruby.rb, line 314 def agent_unlink(scanner_id, agent_id) http_delete(:uri => "/scanners/#{scanner_id}/agents/#{agent_id}", :fields => header) end
Returns details of the specified asset.
Reference: developer.tenable.com/reference#assets-asset-info
# File lib/tenable-ruby.rb, line 337 def asset_info(asset_uuid) http_get(:uri => "/assets/#{asset_uuid}", :fields => header) end
Tries to authenticate to the tenable.io REST JSON interface using username/password or API keys
# File lib/tenable-ruby.rb, line 84 def authenticate if @credentials[:username] and @credentials[:password] payload = { :username => @credentials[:username], :password => @credentials[:password], :json => 1, :authenticationmethod => true } response = http_post(:uri => "/session", :data => payload) if response['token'] @token = "token=#{response['token']}" @header = {'X-Cookie' => @token} else raise TenableRuby::Error::AuthenticationError, "Authentication failed. Could not authenticate using username/password." end elsif @credentials[:access_key] and @credentials[:secret_key] @header = {'X-ApiKeys' => "accessKey=#{@credentials[:access_key]}; secretKey=#{@credentials[:secret_key]}"} else raise TenableRuby::Error::AuthenticationError, "Authentication credentials were not provided. You must " \ "provide either a username and password or an API access key and secret key (these can be generated at " \ "https://cloud.tenable.com/app.html#/settings/my-account/api-keys." end end
Creates a new target group for the current user.
Reference: developer.tenable.com/reference#target-groups-create
# File lib/tenable-ruby.rb, line 729 def create_target_group(name, members, acls: nil) http_post(:uri => "/target-groups", :fields => header, :data => {:name => name, :members => members, :acls => acls}) end
Deletes a target group.
Reference: developer.tenable.com/reference#target-groups-delete
# File lib/tenable-ruby.rb, line 763 def delete_target_group(group_id) http_delete(:uri => "/target-groups/#{group_id}", :fields => header) end
Returns details for the given template
Reference: developer.tenable.com/reference#editor-template-details
# File lib/tenable-ruby.rb, line 223 def editor_templates (type, uuid) http_get(:uri => "/editor/#{type}/templates/#{uuid}", :fields => header) end
Returns the server version and other properties
Reference: developer.tenable.com/reference#server-properties
# File lib/tenable-ruby.rb, line 113 def get_server_properties http_get(:uri => "/server/properties", :fields => header) end
Returns details for the specified target group.
Reference: developer.tenable.com/reference#target-groups-details
# File lib/tenable-ruby.rb, line 746 def get_target_group(group_id) http_get(:uri => "/target-groups/#{group_id}", :fields => header) end
Returns details for the given host
Reference: developer.tenable.com/reference#scans-host-details
# File lib/tenable-ruby.rb, line 436 def host_details(scan_id, host_id, history_id: nil) uri = "/scans/#{scan_id}/hosts/#{host_id}" unless history_id.nil? uri += "?history_id=#{history_id}" end http_get(:uri => uri, :fields => header) end
Returns an inventory of an image by ID.
Reference: developer.tenable.com/reference#container-security-containers-image-inventory
# File lib/tenable-ruby.rb, line 649 def image_inventory(image_id) http_get(:uri => "/container-security/api/v1/container/#{policy_id}/status", :fields => header) end
Returns the status of a job by specifying an image ID to determine if the job is still queued, in progress, or has completed.
Reference: developer.tenable.com/reference#container-security-jobs-job-status-by-image-id
# File lib/tenable-ruby.rb, line 665 def image_status(image_id) http_get(:uri => "/container-security/api/v1/jobs/image_status?image_id=#{image_id}", :fields => header) end
Returns the status of a job by specifying an image digest to determine if the job is still queued, in progress, or has completed.
Reference: developer.tenable.com/reference#container-security-jobs-job-status-by-image-digest
# File lib/tenable-ruby.rb, line 673 def image_status_digest(image_digest) http_get(:uri => "/container-security/api/v1/jobs/image_status_digest?image_digest=#{image_digest}", :fields => header) end
initialize quick scan defaults: these will be used when not specifying defaults
Usage:
n.init_quick_defaults()
# File lib/tenable-ruby.rb, line 41 def init_quick_defaults @quick_defaults = Hash.new @quick_defaults['enabled'] = false @quick_defaults['launch'] = 'ONETIME' @quick_defaults['launch_now'] = true @quick_defaults['description'] = 'Created with tenable-ruby https//gitlab.com/intruder/tenable-ruby' end
Returns the status of a job that you specify by ID to determine if the job is still queued, in progress, or has completed.
Reference: developer.tenable.com/reference#container-security-jobs-job-status
# File lib/tenable-ruby.rb, line 657 def job_status(job_id) http_get(:uri => "/container-security/api/v1/jobs/status?job_id=#{job_id}", :fields => header) end
Returns a list of all containers.
Reference: developer.tenable.com/reference#container-security-containers-list-containers
# File lib/tenable-ruby.rb, line 641 def list_containers() http_get(:uri => "/container-security/api/v1/container/list", :fields => header) end
Returns the list of plugin families
Reference: developer.tenable.com/reference#plugins-families
# File lib/tenable-ruby.rb, line 199 def list_families http_get(:uri => "/plugins/families", :fields => header) end
Returns the current user's scan folders
Reference: # developer.tenable.com/reference#folders-list
# File lib/tenable-ruby.rb, line 183 def list_folders http_get(:uri => "/folders", :fields => header) end
Returns a list of active Container Security jobs
Reference: developer.tenable.com/reference#container-security-jobs-list-jobs
# File lib/tenable-ruby.rb, line 681 def list_jobs() http_get(:uri => "/container-security/api/v1/jobs/list", :fields => header) end
Returns the list of plugins in a family
Reference: developer.tenable.com/reference#plugins-family-details
# File lib/tenable-ruby.rb, line 207 def list_plugins(family_id) http_get(:uri => "/plugins/families/#{family_id}", :fields => header) end
Returns the policy list
Reference: developer.tenable.com/reference#policies-list
# File lib/tenable-ruby.rb, line 167 def list_policies http_get(:uri => "/policies", :fields => header) end
Returns the scanner list
Reference: developer.tenable.com/reference#scanners-list
# File lib/tenable-ruby.rb, line 191 def list_scanners http_get(:uri => "/scanners", :fields => header) end
Returns the current target groups.
Reference: developer.tenable.com/reference#target-groups-list
# File lib/tenable-ruby.rb, line 738 def list_target_groups http_get(:uri => "/target-groups", :fields => header) end
Returns the template list
Reference: developer.tenable.com/reference#editor-list-templates
# File lib/tenable-ruby.rb, line 215 def list_templates(type) http_get(:uri => "/editor/#{type}/templates", :fields => header) end
Returns the user list
Reference: developer.tenable.com/reference#users-list
# File lib/tenable-ruby.rb, line 175 def list_users http_get(:uri => "/users", :fields => header) end
Returns details for a given plugin
Reference: developer.tenable.com/reference#plugins-plugin-details
# File lib/tenable-ruby.rb, line 231 def plugin_details(plugin_id) http_get(:uri => "/plugins/plugin/#{plugin_id}", :fields => header) end
Checks the compliance of an image that you specify by ID against your policies.
Reference: developer.tenable.com/reference#container-security-policy-policy-compliance-by-id
# File lib/tenable-ruby.rb, line 689 def policy_compliance_by_id(image_id) http_get(:uri => "/container-security/api/v1/policycompliance?image_id=#{image_id}", :fields => header) end
Checks the compliance of an image that you specify by name against your policies.
Reference: developer.tenable.com/reference#container-security-policy-policy-compliance-by-name
# File lib/tenable-ruby.rb, line 697 def policy_compliance_by_name(image) http_get(:uri => "/container-security/api/v1/compliancebyname?image=#{image}", :fields => header) end
Changes the parameters of a policy
Reference: developer.tenable.com/reference#policies-configure
# File lib/tenable-ruby.rb, line 506 def policy_configure(policy_id, template_id, plugins, settings) options = { :uri => "/policies/#{policy_id}", :fields => header, :ctype => 'application/json', :body => { :uuid => template_id, :audits => {}, :credentials => {delete: []}, :plugins => plugins, :settings => settings }.to_json } http_put(options) end
Copy a policy
Reference: developer.tenable.com/reference#policies-copy
# File lib/tenable-ruby.rb, line 493 def policy_copy(policy_id) options = { :uri => "/policies/#{policy_id}/copy", :fields => header, :ctype => 'application/json' } http_post(options) end
Creates a policy
Reference: developer.tenable.com/reference#policies-create
# File lib/tenable-ruby.rb, line 473 def policy_create(template_id, plugins, settings) options = { :uri => "/policies/", :fields => header, :ctype => 'application/json', :body => { :uuid => template_id, :audits => {}, :credentials => {delete: []}, :plugins => plugins, :settings => settings }.to_json } http_post(options) end
Delete a policy
Reference: developer.tenable.com/reference#policies-delete
# File lib/tenable-ruby.rb, line 526 def policy_delete(policy_id) response = http_delete(:uri => "/policies/#{policy_id}", :fields => header) response.code end
Returns details for the given policy
Reference: developer.tenable.com/reference#policies-details
# File lib/tenable-ruby.rb, line 465 def policy_details(policy_id) http_get(:uri => "/policies/#{policy_id}", :fields => header) end
Returns a report in JSON format for a container that you specify by ID. Note: If you do not have the container_id, you can call the list-containers endpoint.
Reference: developer.tenable.com/reference#container-security-reports-report-by-container-id
# File lib/tenable-ruby.rb, line 705 def report_by_container_id(container_id) http_get(:uri => "/container-security/api/v1/reports/show?container_id=#{container_id}", :fields => header) end
Returns a report in JSON format for an image digest.
Reference: developer.tenable.com/reference#container-security-reports-report-by-image-digest
# File lib/tenable-ruby.rb, line 721 def report_by_image_digest(image_digest) http_get(:uri => "/container-security/api/v1/reports/by_image_digest?image_digest=#{image_digest}", :fields => header) end
Returns a report in JSON format for an image that you specify by ID. Note: If you do not have the image_id, you can call the list-images endpoint.
Reference: developer.tenable.com/reference#container-security-reports-report-by-image-id
# File lib/tenable-ruby.rb, line 713 def report_by_image_id(image_id) http_get(:uri => "/container-security/api/v1/reports/by_image?image_id=#{image_id}", :fields => header) end
Download an exported scan
Reference: developer.tenable.com/reference#scans-export-download
# File lib/tenable-ruby.rb, line 457 def report_download(scan_id, file_id) http_get(:uri => "/scans/#{scan_id}/export/#{file_id}/download", :raw_content => true, :fields => header) end
use download scan API call to save a report as file
# File lib/tenable-ruby.rb, line 630 def report_download_file(scan_id, format, output_file_name) report_content = report_download_quick(scan_id, format) File.open(output_file_name, 'w') do |f| f.write(report_content) end end
use download scan API call to download a report in raw format
# File lib/tenable-ruby.rb, line 617 def report_download_quick(scan_id, format) export_details = scan_export(scan_id, format) # ready, loading while (export_status = scan_export_status(scan_id, export_details['file'])['status']) != "ready" do if export_status.nil? or export_status == '' or export_status == "error" raise TenableRuby::Error::TenableError, "Tenable.io returned an error while exporting the scan" end sleep @defsleep end report_download(scan_id, export_details['file']) end
Creates a scan
Reference: developer.tenable.com/reference#scans-create
# File lib/tenable-ruby.rb, line 345 def scan_create(uuid, settings) payload = { :uuid => uuid, :settings => settings, :json => 1 }.to_json http_post(:uri => "/scans", :body => payload, :fields => header, :ctype => 'application/json') end
Deletes a scan. NOTE: Scans in running, paused or stopping states can not be deleted.
Reference: developer.tenable.com/reference#scans-delete
# File lib/tenable-ruby.rb, line 428 def scan_delete(scan_id) http_delete(:uri => "/scans/#{scan_id}", :fields => header) end
Returns details for the given scan
Reference: developer.tenable.com/reference#scans-details
# File lib/tenable-ruby.rb, line 374 def scan_details(scan_id) http_get(:uri => "/scans/#{scan_id}", :fields => header) end
Export the given scan. Once requested, the file can be downloaded using the export download method upon receiving a “ready” status from the export status method.
Reference: developer.tenable.com/reference#scans-export-request
# File lib/tenable-ruby.rb, line 407 def scan_export(scan_id, format) payload = { :format => format }.to_json http_post(:uri => "/scans/#{scan_id}/export", :body => payload, :ctype => 'application/json', :fields => header) end
Check the file status of an exported scan. When an export has been requested, it is necessary to poll this endpoint until a “ready” status is returned, at which point the file is complete and can be downloaded using the export download endpoint.
Reference: developer.tenable.com/reference#scans-export-status
# File lib/tenable-ruby.rb, line 420 def scan_export_status(scan_id, file_id) http_get(:uri => "/scans/#{scan_id}/export/#{file_id}/status", :fields => header) end
Parse the scan status command to determine if a scan has finished
# File lib/tenable-ruby.rb, line 607 def scan_finished?(scan_id) status = scan_status(scan_id) if status == 'completed' or status == 'canceled' or status == 'imported' true else false end end
Launches a scan
Reference: developer.tenable.com/reference#scans-launch
# File lib/tenable-ruby.rb, line 358 def scan_launch(scan_id) http_post(:uri => "/scans/#{scan_id}/launch", :fields => header) end
Get List of Scans
Reference: developer.tenable.com/reference#scans-list
# File lib/tenable-ruby.rb, line 366 def scan_list http_get(:uri => "/scans", :fields => header) end
Pauses a scan
Reference: developer.tenable.com/reference#scans-pause
# File lib/tenable-ruby.rb, line 382 def scan_pause(scan_id) http_post(:uri => "/scans/#{scan_id}/pause", :fields => header) end
Performs scan with scan policy provided (uuid of policy or policy name). Name is your scan name and opts is your scan configuration hash (scan_folder is optional - folder where to save the scan (if that folder exists)) (scanner_id is optional - ID of the scanner/cloud scanner you want to run this scan on)
returns: JSON parsed object with scan info
# File lib/tenable-ruby.rb, line 556 def scan_quick_policy(policyname, name, opts = {}, scan_folder = nil, scanner_id = nil) policies = list_policies['policies'] if policies.nil? raise TenableRuby::Error::TenableError, "Tenable API request 'list_policies' responded with 'nil'" end selected_policies = policies.select do |pol| pol['id'] == policyname or pol['name'] == policyname end if selected_policies.size == 0 raise TenableRuby::Error::TenableError, "Policy #{policyname} does not exist in this Tenable account" end policy = selected_policies.first template_uuid = policy['template_uuid'] settings = Hash.new settings.merge!(@quick_defaults) settings.merge!(opts) settings['name'] = name settings['policy_id'] = policy['id'] if scan_folder.is_a?(Integer) settings['folder_id'] = scan_folder elsif scan_folder.is_a?(String) folders = list_folders['folders'] if folders.nil? raise TenableRuby::Error::TenableError, "Tenable API request 'list_folders' responded with 'nil'" end selected_folder = folders.find { |f| f['name'] == scan_folder } if selected_folder settings['folder_id'] = selected_folder['id'] else raise TenableRuby::Error::TenableError, "Could not find folder with name #{scan_folder}" end end unless scanner_id.nil? settings['scanner_id'] = scanner_id end scan_create(template_uuid, settings) end
Performs scan with templatename provided (name, title or uuid of scan). Name is your scan name and targets are targets for scan
returns: JSON parsed object with scan info
# File lib/tenable-ruby.rb, line 535 def scan_quick_template(templatename, name, targets) templates = list_templates('scan')['templates'].select do |temp| temp['uuid'] == templatename or temp['name'] == templatename or temp['title'] == templatename end if templates.nil? return nil end template_uuid = templates.first['uuid'] settings = editor_templates('scan', template_uuid) settings.merge!(@quick_defaults) settings['name'] = name settings['text_targets'] = targets scan_create(template_uuid, settings) end
Resumes a scan
Reference: developer.tenable.com/reference#scans-resume
# File lib/tenable-ruby.rb, line 390 def scan_resume(scan_id) http_post(:uri => "/scans/#{scan_id}/resume", :fields => header) end
Returns the latest status for a scan.
Reference: developer.tenable.com/reference#scans-get-latest-status
# File lib/tenable-ruby.rb, line 597 def scan_status(scan_id) response = http_get(:uri => "/scans/#{scan_id}/latest-status", :fields => header) if response.is_a?(Hash) and response.has_key?('status') response['status'] else raise TenableRuby::Error::TenableError, "Tenable.io did not return a valid status response" end end
Stops a scan
Reference: developer.tenable.com/reference#scans-stop
# File lib/tenable-ruby.rb, line 398 def scan_stop(scan_id) http_post(:uri => "/scans/#{scan_id}/stop", :fields => header) end
Returns the output for a specified plugin.
Reference: developer.tenable.com/reference#scans-plugin-output
# File lib/tenable-ruby.rb, line 448 def scans_plugin_output(scan_id, host_id, plugin_id) uri = "/scans/#{scan_id}/hosts/#{host_id}/plugins/#{plugin_id}" http_get(:uri => uri, :fields => header) end
Returns the server status
Reference: developer.tenable.com/reference#server-status
# File lib/tenable-ruby.rb, line 239 def server_status http_get(:uri => "/server/status", :fields => header) end
Updates a target group.
Reference: developer.tenable.com/reference#target-groups-edit
# File lib/tenable-ruby.rb, line 754 def update_target_group(group_id, name, members, acls: nil) http_put(:uri => "/target-groups/#{group_id}", :fields => header, :data => {:name => name, :members => members, :acls => acls}) end
Creates a new user
Reference: developer.tenable.com/reference#users-create
# File lib/tenable-ruby.rb, line 121 def user_add(username, password, permissions, type) payload = { :username => username, :password => password, :permissions => permissions, :type => type, :json => 1 } http_post(:uri => "/users", :fields => header, :data => payload) end
Changes the password for the given user
Reference: developer.tenable.com/reference#users-password
# File lib/tenable-ruby.rb, line 145 def user_chpasswd(user_id, password) payload = { :password => password, :json => 1 } response = http_put(:uri => "/users/#{user_id}/chpasswd", :data => payload, :fields => header) response.code end
Deletes a user
Reference: developer.tenable.com/reference#users-delete
# File lib/tenable-ruby.rb, line 136 def user_delete(user_id) response = http_delete(:uri => "/users/#{user_id}", :fields => header) response.code end
Logs the current user out and destroys the session
Reference: developer.tenable.com/reference#session-destroy
# File lib/tenable-ruby.rb, line 158 def user_logout response = http_delete(:uri => "/session", :fields => header) response.code end
Private Instance Methods
Perform HTTP delete method with uri, data and fields
returns: HTTP result object
# File lib/tenable-ruby.rb, line 813 def http_delete(opts = {}) response = http_delete_low(opts) if response.is_a?(Hash) and response.has_key?('error') and response['error'] == 'Invalid Credentials' authenticate http_delete_low(opts) response else response end end
# File lib/tenable-ruby.rb, line 824 def http_delete_low(opts = {}) uri = opts[:uri] fields = opts[:fields] || {} response = nil tries = @httpretry request = Net::HTTP::Delete.new(uri) fields.each_pair do |name, value| request.add_field(name, value) end begin tries -= 1 response = @connection.request(request) rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e if tries > 0 sleep @httpsleep retry else return response end rescue URI::InvalidURIError return response end end
Perform HTTP get method with uri and fields
returns: JSON parsed object (if JSON parseable)
# File lib/tenable-ruby.rb, line 854 def http_get(opts = {}) raw_content = opts[:raw_content] || false response = http_get_low(opts) if !raw_content if response.is_a?(Hash) and response.has_key?('error') and response['error'] == 'Invalid Credentials' authenticate response = http_get_low(opts) return response else return response end else response end end
# File lib/tenable-ruby.rb, line 870 def http_get_low(opts = {}) uri = opts[:uri] fields = opts[:fields] || {} raw_content = opts[:raw_content] || false tries = @httpretry request = Net::HTTP::Get.new(uri) fields.each_pair do |name, value| request.add_field(name, value) end begin tries -= 1 response = @connection.request(request) rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e if tries > 0 sleep @httpsleep retry else raise TenableRuby::Error::TenableError.new("#{e}: No more retries for http GET '#{opts[:uri]}'") end rescue URI::InvalidURIError => e raise TenableRuby::Error::TenableError.new("#{e}: http GET '#{opts[:uri]}'") end if response.code.to_s != "200" raise TenableRuby::Error::TenableError.new(response: response), "Tenable API request '#{opts[:uri]}' responded with response code #{response.code}" end if !raw_content parse_json(response.body) else response.body end end
Perform HTTP post method with uri, data, body and fields
returns: JSON parsed object (if JSON parseable)
# File lib/tenable-ruby.rb, line 910 def http_post(opts = {}) if opts.has_key?(:authenticationmethod) # i know authzmethod = opts.delete(:authorizationmethod) is short, but not readable authzmethod = opts[:authenticationmethod] opts.delete(:authenticationmethod) end response = http_post_low(opts) if response.is_a?(Hash) and response.has_key?('error') and response['error'] == 'Invalid Credentials' unless authzmethod authenticate response = http_post_low(opts) return response end else response end end
# File lib/tenable-ruby.rb, line 928 def http_post_low(opts = {}) uri = opts[:uri] data = opts[:data] fields = opts[:fields] || {} body = opts[:body] ctype = opts[:ctype] tries = @httpretry request = Net::HTTP::Post.new(uri) request.set_form_data(data) unless (data.nil? || data.empty?) request.body = body unless (body.nil? || body.empty?) request['Content-Type'] = ctype unless (ctype.nil? || ctype.empty?) fields.each_pair do |name, value| request.add_field(name, value) end begin tries -= 1 response = @connection.request(request) rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e if tries > 0 sleep @httpsleep retry else raise TenableRuby::Error::TenableError.new("#{e}: No more retries for http POST '#{opts[:uri]}'") end rescue URI::InvalidURIError => e raise TenableRuby::Error::TenableError.new("#{e}: http POST '#{opts[:uri]}'") end if response.code.to_s != "200" raise TenableRuby::Error::TenableError.new(response: response), "Tenable API request '#{opts[:uri]}' responded with response code #{response.code}" end parse_json(response.body) end
Perform HTTP put method with uri, data and fields
returns: HTTP result object
# File lib/tenable-ruby.rb, line 772 def http_put(opts = {}) response = http_put_low(opts) if response.is_a?(Hash) and response.has_key?('error') and response['error'] == 'Invalid Credentials' authenticate http_put_low(opts) else response end end
# File lib/tenable-ruby.rb, line 782 def http_put_low(opts = {}) uri = opts[:uri] data = opts[:data] fields = opts[:fields] || {} response = nil tries = @httpretry request = Net::HTTP::Put.new(uri) request.set_form_data(data) unless (data.nil? || data.empty?) fields.each_pair do |name, value| request.add_field(name, value) end begin tries -= 1 response = @connection.request(request) rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e if tries > 0 sleep @httpsleep retry else return response end rescue URI::InvalidURIError return response end end
Perform JSON parsing of body
returns: JSON parsed object (if JSON parseable)
# File lib/tenable-ruby.rb, line 969 def parse_json(body) parsed_json = {} begin parsed_json = JSON.parse(body) rescue JSON::ParserError end parsed_json end