Skip to content

Commit

Permalink
Travis Insights integration
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriiMysko authored and vitalied committed Mar 7, 2022
1 parent 99fd627 commit 80b231a
Show file tree
Hide file tree
Showing 90 changed files with 3,391 additions and 5 deletions.
29 changes: 25 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,32 @@ logs/
log/

.yardoc
.coverage
*.env
.ruby-gemset
.history

#IDEs
.idea

.history
.byebug_history

# Ignore Rubocop files
.rubocop-*

# Ignore coverage reports
coverage/
.coverage/

# Ignore editor specific configs
/.idea
/.vscode
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
.generators
.rakeTasks

# System Files
.DS_Store
Thumbs.db
266 changes: 266 additions & 0 deletions lib/travis/api/v3/insights_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
# frozen_string_literal: true

module Travis::API::V3
class InsightsClient
class ConfigurationError < StandardError; end

def initialize(user_id)
@user_id = user_id
end

def user_notifications(filter, page, active, sort_by, sort_direction)
query_string = query_string_from_params(
value: filter,
page: page || '1',
active: active,
order: sort_by,
order_dir: sort_direction
)
response = connection.get("/user_notifications?#{query_string}")

handle_errors_and_respond(response) do |body|
notifications = body['data'].map do |notification|
Travis::API::V3::Models::InsightsNotification.new(notification)
end

Travis::API::V3::Models::InsightsCollection.new(notifications, body.fetch('total_count'))
end
end

def toggle_snooze_user_notifications(notification_ids)
response = connection.put('/user_notifications/toggle_snooze', snooze_ids: notification_ids)

handle_errors_and_respond(response)
end

def user_plugins(filter, page, active, sort_by, sort_direction)
query_string = query_string_from_params(
value: filter,
page: page || '1',
active: active,
order: sort_by,
order_dir: sort_direction
)
response = connection.get("/user_plugins?#{query_string}")

handle_errors_and_respond(response) do |body|
plugins = body['data'].map do |plugin|
Travis::API::V3::Models::InsightsPlugin.new(plugin)
end

Travis::API::V3::Models::InsightsCollection.new(plugins, body.fetch('total_count'))
end
end

def create_plugin(params)
response = connection.post("/user_plugins", user_plugin: params)
handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsPlugin.new(body['plugin'])
end
end

def toggle_active_plugins(plugin_ids)
response = connection.put('/user_plugins/toggle_active', toggle_ids: plugin_ids)

handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsCollection.new([], 0)
end
end

def delete_many_plugins(plugin_ids)
response = connection.delete('/user_plugins/delete_many', delete_ids: plugin_ids)

handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsCollection.new([], 0)
end
end

def run_scan
response = connection.get('/user_plugins/run_scan')

handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsCollection.new([], 0)
end
end

def generate_key(plugin_name, plugin_type)
response = connection.get('/user_plugins/generate_key', name: plugin_name, plugin_type: plugin_type)

handle_errors_and_respond(response) do |body|
body
end
end

def authenticate_key(params)
response = connection.post('/user_plugins/authenticate_key', params)

handle_errors_and_respond(response) do |body|
body
end
end

def template_plugin_tests(plugin_type)
response = connection.get("/user_plugins/#{plugin_type}/template_plugin_tests")

handle_errors_and_respond(response) do |body|
body
end
end

def get_scan_logs(plugin_id, last_id)
params = last_id ? { last: last_id, poll: true } : {}
response = connection.get("/user_plugins/#{plugin_id}/get_scan_logs", params)

handle_errors_and_respond(response) do |body|
body
end
end

def probes(filter, page, active, sort_by, sort_direction)
query_string = query_string_from_params(
value: filter,
page: page || '1',
active: active,
order: sort_by,
order_dir: sort_direction
)
response = connection.get("/probes?#{query_string}")

handle_errors_and_respond(response) do |body|
probes = body['data'].map do |probe|
Travis::API::V3::Models::InsightsProbe.new(probe)
end

Travis::API::V3::Models::InsightsCollection.new(probes, body.fetch('total_count'))
end
end

def create_probe(params)
response = connection.post("/probes", test_template: params)
handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsProbe.new(body)
end
end

def update_probe(params)
response = connection.patch("/probes/#{params['probe_id']}", params)
handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsProbe.new(body)
end
end

def get_probe(params)
response = connection.get("/probes/#{params['probe_id']}/template_test", params)
handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsProbe.new(body)
end
end

def toggle_active_probes(probe_ids)
response = connection.put('/probes/toggle_active', toggle_ids: probe_ids)

handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsCollection.new([], 0)
end
end

def delete_many_probes(probe_ids)
response = connection.delete('/probes/delete_many', delete_ids: probe_ids)

handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsCollection.new([], 0)
end
end

def sandbox_plugins(plugin_type)
response = connection.post('/sandbox/plugins', plugin_type: plugin_type)

handle_errors_and_respond(response) do |body|
body
end
end

def sandbox_plugin_data(plugin_id)
response = connection.post('/sandbox/plugin_data', plugin_id: plugin_id)

handle_errors_and_respond(response) do |body|
body
end
end

def sandbox_run_query(plugin_id, query)
response = connection.post('/sandbox/run_query', plugin_id: plugin_id, query: query)

handle_errors_and_respond(response) do |body|
body
end
end

def public_key
response = connection.get('/api/v1/public_keys/latest.json')

handle_errors_and_respond(response) do |body|
Travis::API::V3::Models::InsightsPublicKey.new(body)
end
end

def search_tags
response = connection.get('/tags')

handle_errors_and_respond(response) do |body|
tags = body.map do |tag|
Travis::API::V3::Models::InsightsTag.new(tag)
end
end
end

private

def handle_errors_and_respond(response)
case response.status
when 200, 201
yield(response.body) if block_given?
when 202
true
when 204
true
when 400
raise Travis::API::V3::ClientError, response.body&.fetch('error', '')
when 403
raise Travis::API::V3::InsufficientAccess, response.body&.fetch('rejection_code', '')
when 404
raise Travis::API::V3::NotFound, response.body&.fetch('error', '')
when 422
raise Travis::API::V3::UnprocessableEntity, response.body&.fetch('error', '')
else
raise Travis::API::V3::ServerError, 'Insights API failed'
end
end

def connection(timeout: 20)
@connection ||= Faraday.new(url: insights_url, ssl: { ca_path: '/usr/lib/ssl/certs' }) do |conn|
conn.headers[:Authorization] = "Token token=\"#{insights_auth_token}\""
conn.headers['X-Travis-User-Id'] = @user_id.to_s
conn.headers['Content-Type'] = 'application/json'
conn.request :json
conn.response :json
conn.options[:open_timeout] = timeout
conn.options[:timeout] = timeout
conn.use OpenCensus::Trace::Integrations::FaradayMiddleware if Travis::Api::App::Middleware::OpenCensus.enabled?
conn.adapter :net_http
end
end

def insights_url
Travis.config.new_insights.insights_url || raise(ConfigurationError, 'No Insights API URL configured!')
end

def insights_auth_token
Travis.config.new_insights.insights_auth_token || raise(ConfigurationError, 'No Insights Auth Token configured!')
end

def query_string_from_params(params)
params.delete_if { |_, v| v.nil? || v.empty? }.to_query
end
end
end
32 changes: 32 additions & 0 deletions lib/travis/api/v3/models/insights_collection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

module Travis::API::V3
class Models::InsightsCollection
def initialize(collection, total_count)
@collection = collection
@total_count = total_count
end

def count(*)
@total_count
end

def limit(*)
self
end

def offset(*)
self
end

def map
return @collection.map unless block_given?

@collection.map { |x| yield x }
end

def to_sql
"insights_query:#{Time.now.to_i}"
end
end
end
19 changes: 19 additions & 0 deletions lib/travis/api/v3/models/insights_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Travis::API::V3
class Models::InsightsNotification
attr_reader :id, :type, :active, :weight, :message, :plugin_name, :plugin_type, :plugin_category, :probe_severity, :description, :description_link

def initialize(attributes = {})
@id = attributes.fetch('id')
@type = attributes.fetch('type')
@active = attributes.fetch('active')
@weight = attributes.fetch('weight')
@message = attributes.fetch('message')
@plugin_name = attributes.fetch('plugin_name')
@plugin_type = attributes.fetch('plugin_type')
@plugin_category = attributes.fetch('plugin_category')
@probe_severity = attributes.fetch('probe_severity')
@description = attributes.fetch('description', '')
@description_link = attributes.fetch('description_link', '')
end
end
end
17 changes: 17 additions & 0 deletions lib/travis/api/v3/models/insights_plugin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Travis::API::V3
class Models::InsightsPlugin
attr_reader :id, :name, :public_id, :plugin_type, :plugin_category, :last_scan_end, :scan_status, :plugin_status, :active

def initialize(attributes = {})
@id = attributes.fetch('id')
@name = attributes.fetch('name')
@public_id = attributes.fetch('public_id')
@plugin_type = attributes.fetch('plugin_type')
@plugin_category = attributes.fetch('plugin_category')
@last_scan_end = attributes.fetch('last_scan_end')
@scan_status = attributes.fetch('scan_status')
@plugin_status = attributes.fetch('plugin_status')
@active = attributes.fetch('active')
end
end
end
Loading

0 comments on commit 80b231a

Please sign in to comment.