Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azure basic images do not get access to LTSS #1248

Merged
merged 5 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@ def payg_billing_code?(iid, identifier)
return true if (identifier.casecmp('sles').zero? && instance_billing_info[:billing_product] == SLES_PRODUCT_IDENTIFIER)
return true if (identifier.casecmp('sles_sap').zero? && SLES4SAP_PRODUCT_IDENTIFIER.include?(instance_billing_info[:marketplace_code]))
end

def allowed_extension?
# method to check if a product (extension) meet the criteria
# to be acivated on SCC or not, i.e. LTSS in Azure Basic VM
true
end
jesusbv marked this conversation as resolved.
Show resolved Hide resolved
end
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

it 'class instance verification provider' do
expect(InstanceVerification::Providers::Example).to receive(:new)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, nil).and_call_original
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, nil).and_call_original.at_least(:once)
allow(File).to receive(:directory?)
allow(Dir).to receive(:mkdir)
allow(FileUtils).to receive(:touch)
Expand Down Expand Up @@ -71,13 +71,18 @@
end

context 'when verification provider returns false' do
let(:plugin_double) { instance_double('InstanceVerification::Providers::Example') }

before do
stub_request(:post, scc_activate_url)
.to_return(
status: 200,
body: { error: 'Unexpected instance verification error has occurred' }.to_json,
headers: {}
)
)
allow(InstanceVerification::Providers::Example).to receive(:new).and_return(plugin_double)
allow(plugin_double).to receive(:allowed_extension?).and_return(true)
allow(plugin_double).to receive(:instance_valid?).and_return(false)
post url, params: payload, headers: headers
end

Expand Down Expand Up @@ -113,7 +118,7 @@

it 'class instance verification provider' do
expect(InstanceVerification::Providers::Example).to receive(:new)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, nil).and_call_original
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, nil).and_call_original.at_least(:once)
allow(File).to receive(:directory?)
allow(Dir).to receive(:mkdir)
allow(FileUtils).to receive(:touch)
Expand Down Expand Up @@ -141,8 +146,9 @@
context 'when verification provider returns false' do
before do
expect(InstanceVerification::Providers::Example).to receive(:new)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double).at_least(:once)
expect(plugin_double).to receive(:instance_valid?).and_return(false)
allow(plugin_double).to receive(:allowed_extension?).and_return(true)
post url, params: payload, headers: headers
end

Expand All @@ -155,8 +161,9 @@
context 'when verification provider raises an unhandled exception' do
before do
expect(InstanceVerification::Providers::Example).to receive(:new)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double).at_least(:once)
expect(plugin_double).to receive(:instance_valid?).and_raise('Custom plugin error')
allow(plugin_double).to receive(:allowed_extension?).and_return(true)
post url, params: payload, headers: headers
end

Expand All @@ -171,9 +178,9 @@

before do
expect(InstanceVerification::Providers::Example).to receive(:new)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double).at_least(:once)
expect(plugin_double).to receive(:instance_valid?).and_raise(InstanceVerification::Exception, 'Custom plugin error')

allow(plugin_double).to receive(:allowed_extension?).and_return(true)
post url, params: payload, headers: headers
end

Expand Down Expand Up @@ -227,9 +234,9 @@
end

before do
allow(InstanceVerification::Providers::Example).to receive(:new)
.with(nil, nil, nil, instance_data).and_return(plugin_double)
allow(InstanceVerification::Providers::Example).to receive(:new).and_return(plugin_double)
allow(plugin_double).to receive(:parse_instance_data).and_return({ InstanceId: 'foo' })
allow(plugin_double).to receive(:allowed_extension?).and_return(true)

FactoryBot.create(:subscription, product_classes: product_classes)
stub_request(:post, scc_activate_url)
Expand Down Expand Up @@ -340,8 +347,9 @@

before do
allow(InstanceVerification::Providers::Example).to receive(:new)
.with(nil, nil, nil, instance_data).and_return(plugin_double)
.and_return(plugin_double)
allow(plugin_double).to receive(:parse_instance_data).and_return({ InstanceId: 'foo' })
allow(plugin_double).to receive(:allowed_extension?).and_return(true)

allow(InstanceVerification).to receive(:update_cache).with('127.0.0.1', system.login, product.id)
FactoryBot.create(:subscription, product_classes: product_classes)
Expand Down Expand Up @@ -380,8 +388,9 @@

before do
allow(InstanceVerification::Providers::Example).to receive(:new)
.with(nil, nil, nil, instance_data).and_return(plugin_double)
.and_return(plugin_double)
allow(plugin_double).to receive(:parse_instance_data).and_return({ InstanceId: 'foo' })
allow(plugin_double).to receive(:allowed_extension?).and_return(true)

allow(InstanceVerification).to receive(:update_cache).with('127.0.0.1', system.login, product.id)
FactoryBot.create(:subscription, product_classes: product_classes)
Expand All @@ -397,7 +406,7 @@
.to_return(status: 201, body: scc_response_body, headers: {})

expect(InstanceVerification).not_to receive(:update_cache).with('127.0.0.1', system.login, product.id)

allow(plugin_double).to receive(:allowed_extension?).and_return(true)
post url, params: payload_no_token, headers: headers
end

Expand All @@ -409,12 +418,16 @@
end

context 'when the system is hybrid' do
before do
allow_any_instance_of(InstanceVerification::Providers::Example).to receive(:allowed_extension?).and_return(true)
end

context "when system doesn't have hw_info" do
let(:system) { FactoryBot.create(:system, :hybrid) }

it 'class instance verification provider' do
expect(InstanceVerification::Providers::Example).to receive(:new)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, nil).and_call_original
.and_call_original.at_least(:once)
allow(File).to receive(:directory?)
allow(Dir).to receive(:mkdir)
allow(FileUtils).to receive(:touch)
Expand Down Expand Up @@ -442,7 +455,8 @@
context 'when verification provider returns false' do
before do
expect(InstanceVerification::Providers::Example).to receive(:new)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double).at_least(:once)
allow(plugin_double).to receive(:allowed_extension?).and_return(true)
expect(plugin_double).to receive(:instance_valid?).and_return(false)
post url, params: payload, headers: headers
end
Expand All @@ -456,7 +470,8 @@
context 'when verification provider raises an unhandled exception' do
before do
expect(InstanceVerification::Providers::Example).to receive(:new)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double)
.with(be_a(ActiveSupport::Logger), be_a(ActionDispatch::Request), payload, instance_data).and_return(plugin_double).at_least(:once)
allow(plugin_double).to receive(:allowed_extension?).and_return(true)
expect(plugin_double).to receive(:instance_valid?).and_raise('Custom plugin error')
post url, params: payload, headers: headers
end
Expand Down Expand Up @@ -514,8 +529,9 @@

before do
allow(InstanceVerification::Providers::Example).to receive(:new)
.with(nil, nil, nil, instance_data).and_return(plugin_double)
.and_return(plugin_double)
allow(plugin_double).to receive(:parse_instance_data).and_return({ InstanceId: 'foo' })
allow(plugin_double).to receive(:allowed_extension?).and_return(true)

FactoryBot.create(:subscription, product_classes: product_classes)
stub_request(:post, scc_activate_url)
Expand Down
8 changes: 8 additions & 0 deletions engines/scc_proxy/lib/scc_proxy/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ def scc_upgrade(auth, product, system_login, mode, logger)
end
end

# rubocop:disable Metrics/ClassLength
class Engine < ::Rails::Engine
isolate_namespace SccProxy
config.generators.api_only = true
Expand Down Expand Up @@ -372,6 +373,12 @@ def has_no_regcode?(auth_header)
protected

def scc_activate_product
product_hash = @product.attributes.symbolize_keys.slice(:identifier, :version, :arch)
unless InstanceVerification.provider.new(logger, request, product_hash, @system.instance_data).allowed_extension?
error = ActionController::TranslatedError.new(N_('Product not supported for this instance'))
error.status = :forbidden
raise error
end
mode = find_mode
unless mode.nil?
# if system is byos or hybrid and there is a token
Expand Down Expand Up @@ -540,5 +547,6 @@ def get_system(systems)
end
end
end
# rubocop:enable Metrics/ClassLength
end
# rubocop:enable Metrics/ModuleLength
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@
end
let(:product) do
FactoryBot.create(
:product, :product_sles, :extension, :with_mirrored_repositories, :with_mirrored_extensions,
:product, :product_sles_ltss, :extension, :with_mirrored_repositories, :with_mirrored_extensions,
base_products: [system_payg.products.first]
)
end
Expand Down Expand Up @@ -415,7 +415,120 @@
allow(File).to receive(:directory?)
allow(FileUtils).to receive(:mkdir_p)
allow(FileUtils).to receive(:touch)
allow(InstanceVerification::Providers::Example).to receive(:new).and_return(plugin_double)
allow(plugin_double).to receive(:allowed_extension?).and_return(true)
allow(InstanceVerification).to receive(:write_cache_file).twice.with(
Rails.application.config.repo_cache_dir, "127.0.0.1-#{system_payg.login}-#{product.id}"
)
allow(InstanceVerification).to receive(:write_cache_file).twice.with(
Rails.application.config.registry_cache_dir, "127.0.0.1-#{system_payg.login}"
)
allow(plugin_double).to receive(:instance_valid?).and_return(true)
end

context 'when LTSS not allowed' do
before do
allow(plugin_double).to receive(:allowed_extension?).and_return(false)
end

it 'raises an error' do
stub_request(:post, scc_register_system_url)
.to_return(status: 403, body: { ok: 'OK' }.to_json, headers: {})

post url, params: payload, headers: headers
data = JSON.parse(response.body)
expect(data['error']).to include('Product not supported for this instance')
end
end
end
end
end

context 'when system has hw info' do
let(:instance_data) { '<document>{"instanceId": "dummy_instance_data"}</document>' }
let(:new_system_token) { 'BBBBBBBB-BBBB-4BBB-9BBB-BBBBBBBBBBBB' }
let(:serialized_service_json) do
V3::ServiceSerializer.new(
product.service,
base_url: URI::HTTP.build({ scheme: response.request.scheme, host: response.request.host }).to_s
).to_json
end

let(:serialized_service_sap_json) do
V3::ServiceSerializer.new(
product_sap.service,
base_url: URI::HTTP.build({ scheme: response.request.scheme, host: response.request.host }).to_s
).to_json
end

context 'when system is connected to SCC' do
let(:system_payg) do
FactoryBot.create(:system, :payg, :with_system_information, :with_activated_base_product, instance_data: instance_data,
system_token: new_system_token)
end
let(:product) do
FactoryBot.create(
:product, :product_sles_ltss, :extension, :with_mirrored_repositories, :with_mirrored_extensions,
base_products: [system_payg.products.first]
)
end
let(:subscription_response) do
{
id: 4206714,
regcode: 'bar',
name: 'SUSE Employee subscription for SUSE Linux Enterprise Server for SAP Applications',
type: 'internal',
status: 'ACTIVE',
starts_at: '2019-03-20T09:48:52.658Z',
expires_at: '2024-03-20T09:48:52.658Z',
system_limit: '100',
systems_count: '156',
virtual_count: nil,
product_classes: [
'AiO',
'7261',
'SLE-HAE-X86',
'7261-BETA',
'SLE-HAE-X86-BETA',
'AiO-BETA',
'7261-ALPHA',
'SLE-HAE-X86-ALPHA',
'AiO-ALPHA'
],
product_ids: [
1959,
1421
],
skus: [],
systems: [
{
id: 3021957,
login: 'SCC_foo',
password: '5ee7273ac6ac4d7f',
last_seen_at: '2019-03-20T14:01:05.424Z'
}
]
}
end

before do
allow(plugin_double).to(
receive(:instance_valid?)
.and_raise(InstanceVerification::Exception, 'Custom plugin error')
)
end

context 'with a valid registration code' do
before do
stub_request(:post, scc_activate_url)
.to_return(
status: 201,
body: { id: 'bar' }.to_json,
headers: {}
)
allow(File).to receive(:directory?)
allow(FileUtils).to receive(:mkdir_p)
allow(FileUtils).to receive(:touch)
allow(InstanceVerification).to receive(:write_cache_file).twice.with(
Rails.application.config.repo_cache_dir, "127.0.0.1-#{system_payg.login}-#{product.id}"
)
Expand Down
17 changes: 17 additions & 0 deletions spec/factories/products.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,23 @@
friendly_version { '15 SP3' }
end

trait :product_sles_ltss do
identifier { 'SLES-LTSS' }
name { 'SUSE Linux Enterprise Server LTSS' }
description { 'SUSE Linux Enterprise offers a comprehensive suite of products...' }
shortname { 'SLES15-SP3-LTSS' }
former_identifier { 'SLES_LTSS' }
product_type { 'extension' }
product_class { 'LTSS' }
release_type { nil }
release_stage { 'released' }
version { '15.3' }
arch { 'x86_64' }
free { false }
cpe { 'cpe:/o:suse:sles:15:sp3' }
friendly_version { '15 SP3' }
end

trait :product_sles_sap do
identifier { 'SLES_SAP' }
name { 'SUSE Linux Enterprise Server' }
Expand Down