class Chelsea::IQClient

IQ audit operations

Constants

COLOR_FAILURE

colors to use when printing message

COLOR_NONE
COLOR_WARNING
DEFAULT_OPTIONS
POLICY_ACTION_FAILURE

Known policy actions

POLICY_ACTION_NONE
POLICY_ACTION_WARNING

Public Class Methods

new(options: DEFAULT_OPTIONS) click to toggle source
# File lib/chelsea/iq_client.rb, line 38
def initialize(options: DEFAULT_OPTIONS)
  @options = options
  @pastel = Pastel.new
  @spinner = Chelsea::Spinner.new
end

Public Instance Methods

poll_status(url) click to toggle source
# File lib/chelsea/iq_client.rb, line 67
def poll_status(url)
  spin = @spinner.spin_msg 'Polling Nexus IQ Server for results'
  loop do
    res = _poll_iq_server(url)
    if res.code == 200
      spin.success('...done.')
      return _handle_response(res)
    end
  rescue StandardError
    sleep(1)
  end
end
post_sbom(sbom) click to toggle source
# File lib/chelsea/iq_client.rb, line 44
def post_sbom(sbom) # rubocop:disable Metrics/MethodLength
  spin = @spinner.spin_msg 'Submitting sbom to Nexus IQ Server'
  @internal_application_id = _get_internal_application_id
  resource = RestClient::Resource.new(
    _api_url,
    user: @options[:username],
    password: @options[:auth_token]
  )
  res = resource.post sbom.to_s, _headers.merge(content_type: 'application/xml')
  if res.code == 202
    spin.success('...done.')
    status_url(res)
  else
    spin.stop('...request failed.')
    nil
  end
end
status_url(res) click to toggle source
# File lib/chelsea/iq_client.rb, line 62
def status_url(res)
  res = JSON.parse(res.body)
  res['statusUrl']
end

Private Instance Methods

_api_url() click to toggle source
# File lib/chelsea/iq_client.rb, line 178
def _api_url
  # rubocop:disable Layout/LineLength
  "#{@options[:server_url]}/api/v2/scan/applications/#{@internal_application_id}/sources/chelsea?stageId=#{@options[:stage]}"
  # rubocop:enable Layout/LineLength
end
_get_internal_application_id() click to toggle source
# File lib/chelsea/iq_client.rb, line 155
def _get_internal_application_id # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
  resource = RestClient::Resource.new(
    _internal_application_id_api_url,
    user: @options[:username],
    password: @options[:auth_token]
  )
  res = resource.get _headers
  if res.code != 200
    puts "failure reading application id: #{@options[:public_application_id]}. response status: #{res.code}"
    return
  end
  body = JSON.parse(res)
  if body['applications'].empty?
    puts "failed to get internal application id for IQ application id: #{@options[:public_application_id]}"
    return
  end
  body['applications'][0]['id']
end
_handle_response(res) click to toggle source
# File lib/chelsea/iq_client.rb, line 91
def _handle_response(res) # rubocop:disable Metrics/MethodLength
  res = JSON.parse(res.body)
  # get absolute report url
  absolute_report_html_url = URI.join(@options[:server_url], res['reportHtmlUrl'])

  case res['policyAction']
  when POLICY_ACTION_FAILURE
    ['Hi! Chelsea here, you have some policy violations to clean up!'\
      "\nReport URL: #{absolute_report_html_url}",
     COLOR_FAILURE, 1]
  when POLICY_ACTION_WARNING
    ['Hi! Chelsea here, you have some policy warnings to peck at!'\
    "\nReport URL: #{absolute_report_html_url}",
     COLOR_WARNING, 0]
  when POLICY_ACTION_NONE
    ['Hi! Chelsea here, no policy violations for this audit!'\
    "\nReport URL: #{absolute_report_html_url}",
     COLOR_NONE, 0]
  else
    ['Hi! Chelsea here, no policy violations for this audit, but unknown policy action!'\
    "\nReport URL: #{absolute_report_html_url}",
     COLOR_FAILURE, 1]
  end
end
_headers() click to toggle source
# File lib/chelsea/iq_client.rb, line 174
def _headers
  { 'User-Agent' => _user_agent }
end
_internal_application_id_api_url() click to toggle source
# File lib/chelsea/iq_client.rb, line 184
def _internal_application_id_api_url
  "#{@options[:server_url]}/api/v2/applications?publicId=#{@options[:public_application_id]}"
end
_poll_iq_server(status_url) click to toggle source
# File lib/chelsea/iq_client.rb, line 116
def _poll_iq_server(status_url)
  resource = RestClient::Resource.new(
    "#{@options[:server_url]}/#{status_url}",
    user: @options[:username],
    password: @options[:auth_token]
  )

  resource.get _headers
end
_poll_status() click to toggle source
# File lib/chelsea/iq_client.rb, line 140
def _poll_status # rubocop:disable Metrics/MethodLength
  return unless @status_url

  loop do
    res = check_status(@status_url)
    if res.code == 200
      puts JSON.parse(res.body)
      break
    end
  rescue RestClient::ResourceNotFound => _e
    print '.'
    sleep(1)
  end
end
_status_url(res) click to toggle source
# File lib/chelsea/iq_client.rb, line 135
def _status_url(res)
  res = JSON.parse(res.body)
  res['statusUrl']
end
_user_agent() click to toggle source
# File lib/chelsea/iq_client.rb, line 188
def _user_agent
  "chelsea/#{Chelsea::VERSION}"
end
status(status_url) click to toggle source
# File lib/chelsea/iq_client.rb, line 126
def status(status_url)
  resource = RestClient::Resource.new(
    "#{@options[:server_url]}/#{status_url}",
    user: @options[:username],
    password: @options[:auth_token]
  )
  resource.get _headers
end