Skip to content

Commit

Permalink
Add data export engine
Browse files Browse the repository at this point in the history
Add tests for data export engine actions
  • Loading branch information
jesusbv committed Jan 15, 2025
1 parent 9444e3f commit c7f851b
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 1 deletion.
5 changes: 5 additions & 0 deletions engines/data_export/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# DataExport
Short description and motivation.

## Usage
How to use my plugin.
13 changes: 13 additions & 0 deletions engines/data_export/bin/rails
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails gems
# installed from the root of your application.

ENGINE_ROOT = File.expand_path('..', __dir__)
ENGINE_PATH = File.expand_path('../lib/data_export/engine', __dir__)
APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)

# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

require 'rails'
2 changes: 2 additions & 0 deletions engines/data_export/config/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DataExport::Engine.routes.draw do # rubocop:disable Lint/EmptyBlock
end
28 changes: 28 additions & 0 deletions engines/data_export/lib/data_export.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
$LOAD_PATH.push File.expand_path(__dir__, '..')

module DataExport
class << self
# rubocop:disable ThreadSafety/ClassAndModuleAttributes
attr_accessor :handler
# rubocop:enable ThreadSafety/ClassAndModuleAttributes
end

class Exception < RuntimeError; end
end

module DataExport::Handlers
end

require 'data_export/engine'
require 'data_export/handler_base'

handlers = Dir.glob(File.join(__dir__, 'data_export/handlers/*.rb'))

raise 'Too many data export handlers found' if handlers.size > 1

# rubocop:disable Lint:UnreachableLoop
handlers.each do |f|
require_relative f
break
end
# rubocop:enable Lint:UnreachableLoop
53 changes: 53 additions & 0 deletions engines/data_export/lib/data_export/engine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module DataExport
class Engine < ::Rails::Engine
isolate_namespace DataExport
config.after_initialize do
# replaces RMT registration for SCC registration
Api::Connect::V3::Subscriptions::SystemsController.class_eval do
after_action :update_info, only: %i[announce_system], if: -> { response.successful? }

def update_info
# no need to check if system is nil
# as the response is successful
return if @system.byos?

data_export_handler = DataExport.handler.new(
@system,
request,
params,
logger
)
data_export_handler.update_info
logger.info "System #{@system.login} info updated by data warehouse handler after announcing the system"
rescue StandardError => e
logger.error('Unexpected data export error has occurred:')
logger.error(e.message)
logger.error("System login: #{@system.login}, IP: #{request.remote_ip}")
logger.error('Backtrace:')
logger.error(e.backtrace)
end
end

Api::Connect::V3::Systems::SystemsController.class_eval do
after_action :update_info, only: %i[update], if: -> { response.successful? }

def update_info
data_export_handler = DataExport.handler.new(
@system,
request,
params,
logger
)
data_export_handler.update_info
logger.info "System #{@system.login} info updated by data warehouse handler after updating the system"
rescue StandardError => e
logger.error('Unexpected data warehouse error has occurred:')
logger.error(e.message)
logger.error("System login: #{@system.login}, IP: #{request.remote_ip}")
logger.error('Backtrace:')
logger.error(e.backtrace)
end
end
end
end
end
12 changes: 12 additions & 0 deletions engines/data_export/lib/data_export/handler_base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class DataExport::HandlerBase
def self.inherited(child_class) # rubocop:disable Lint/MissingSuper
DataExport.handler = child_class
end

def initialize(system, request, params, logger)
@system = system
@request = request
@params = params
@logger = logger
end
end
5 changes: 5 additions & 0 deletions engines/data_export/lib/data_export/handlers/example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class DataExport::Handlers::Example < DataExport::HandlerBase
def update_info
true
end
end
4 changes: 4 additions & 0 deletions engines/data_export/lib/tasks/data_warehouse_tasks.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# desc "Explaining what the task does"
# task :data_export do
# # Task goes here
# end
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require 'rails_helper'

describe Api::Connect::V3::Subscriptions::SystemsController, type: :request do
describe '#announce_system' do
let(:instance_data) { '<instance_data/>' }

context 'using SCC generated credentials (BYOS mode)' do
let(:scc_register_system_url) { 'https://scc.suse.com/connect/subscriptions/systems' }
let(:scc_register_response) do
{
id: 5684096,
login: 'SCC_foo',
password: '1234',
last_seen_at: '2021-10-24T09:48:52.658Z'
}.to_json
end
let(:params) do
{
hostname: 'test',
proxy_byos_mode: :payg,
instance_data: instance_data,
hwinfo:
{
hostname: 'test',
cpus: '1',
sockets: '1',
hypervisor: 'Xen',
arch: 'x86_64',
uuid: 'ec235f7d-b435-e27d-86c6-c8fef3180a01',
cloud_provider: 'super_cloud'
}
}
end

context 'valid credentials' do
let(:plugin_double) { instance_double('DataExport::Handlers::Example') }

before do
allow(DataExport::Handlers::Example).to receive(:new).and_return(plugin_double)
allow(plugin_double).to receive(:update_info)
stub_request(:post, scc_register_system_url)
.to_return(
status: 201,
body: scc_register_response.to_s,
headers: {}
)
end

it 'saves the data' do
expect(plugin_double).to receive(:update_info)
post '/connect/subscriptions/systems', params: params, headers: { HTTP_AUTHORIZATION: 'Token token=' }
end

context 'export fails' do
let(:logger) { instance_double('RMT::Logger').as_null_object }

before do
allow(DataExport::Handlers::Example).to receive(:new).and_return(plugin_double)
allow(plugin_double).to receive(:update_info).and_raise('foo')
allow(Rails.logger).to receive(:error)
stub_request(:post, scc_register_system_url)
.to_return(
status: 201,
body: scc_register_response.to_s,
headers: {}
)
end

it 'does not save the data and log error' do
expect(plugin_double).to receive(:update_info)
expect(Rails.logger).to receive(:error)
post '/connect/subscriptions/systems', params: params, headers: { HTTP_AUTHORIZATION: 'Token token=' }
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require 'rails_helper'

RSpec.describe Api::Connect::V3::Systems::SystemsController do
include_context 'auth header', :system, :login, :password
include_context 'version header', 3
include_context 'user-agent header'
include_context 'zypp user-agent header'

let(:system) { FactoryBot.create(:system, hostname: 'initial') }
let(:url) { '/connect/systems' }
let(:headers) { auth_header.merge(version_header) }
let(:hwinfo) do
{
cpus: 16,
sockets: 1,
arch: 'x86_64',
hypervisor: 'XEN',
uuid: 'f46906c5-d87d-4e4c-894b-851e80376003',
cloud_provider: 'testcloud'
}
end
let(:payload) { { hostname: 'test', hwinfo: hwinfo } }
let(:system_uptime) { system.system_uptimes.first }
let(:plugin_double) { instance_double('DataExport::Handlers::Example') }

describe '#update' do
subject(:update_action) { put url, params: payload, headers: headers }

context 'when update success' do
before { allow(DataExport::Handlers::Example).to receive(:new).and_return(plugin_double) }

context 'when data export success' do
before { allow(plugin_double).to receive(:update_info) }

it do
expect(plugin_double).to receive(:update_info)
expect { update_action }.to change { system.reload.hostname }.from('initial').to(payload[:hostname])
end
end

context 'when data export fails' do
before do
allow(plugin_double).to receive(:update_info).and_raise('foo')
allow(Rails.logger).to receive(:error)
end

it do
expect(plugin_double).to receive(:update_info)
expect(Rails.logger).to receive(:error)
update_action
end
end
end
end
end
2 changes: 1 addition & 1 deletion engines/scc_proxy/lib/scc_proxy/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def announce_system
system_information: system_information,
proxy_byos_mode: :payg,
instance_data: instance_data
)
)
else
request.request_parameters['proxy_byos_mode'] = 'byos'
response = SccProxy.announce_system_scc(auth_header, request.request_parameters)
Expand Down

0 comments on commit c7f851b

Please sign in to comment.