Skip to content

Commit

Permalink
Merge pull request #1248 from SUSE/azure-basic-ltss
Browse files Browse the repository at this point in the history
Azure basic images do not get access to LTSS
  • Loading branch information
jesusbv authored Nov 26, 2024
2 parents 02ac780 + a778f30 commit e5e2ae8
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 17 deletions.
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
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

0 comments on commit e5e2ae8

Please sign in to comment.