From ea4d09f4690369e2cf6b847608e4ad51b7987e61 Mon Sep 17 00:00:00 2001 From: Jesus Bermudez Velazquez Date: Tue, 27 Aug 2024 17:56:49 +0100 Subject: [PATCH 1/9] Update system from hybrid to payg if no more non free products active When deactivating a product on a hybrid system, if there are no more non free product active for that system on SCC, that system is no longer hybrid but payg and should get updated on the db --- engines/scc_proxy/lib/scc_proxy/engine.rb | 12 ++ .../v4/systems/products_controller_spec.rb | 104 ++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index 1114de827..7a52c8ab0 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -405,6 +405,9 @@ def scc_deactivate_product # it is OK to remove it from SCC response = SccProxy.deactivate_product_scc(auth, @product, @system.system_token) handle_response(response) + # if the system does not have more non free products activated on SCC + # system should turn to hybrid + @system.payg! if no_more_activations scc_systems_activations elsif result[:message].downcase.include?('unexpected error') raise ActionController::TranslatedError.new(result[:message]) end @@ -429,6 +432,15 @@ def handle_response(response) raise ActionController::TranslatedError.new(error['error']) end end + + def no_more_activations(scc_systems_activations) + active_products_classes = scc_systems_activations.map do |act| + if act['status'].casecmp('active').zero? && act['service']['product']['product_class'] != @product.product_class + act['service']['product']['product_class'] + end + end.flatten.compact + active_products_classes.empty? + end end Api::Connect::V3::Systems::SystemsController.class_eval do diff --git a/engines/scc_proxy/spec/requests/api/connect/v4/systems/products_controller_spec.rb b/engines/scc_proxy/spec/requests/api/connect/v4/systems/products_controller_spec.rb index 4a38985e5..586921c26 100644 --- a/engines/scc_proxy/spec/requests/api/connect/v4/systems/products_controller_spec.rb +++ b/engines/scc_proxy/spec/requests/api/connect/v4/systems/products_controller_spec.rb @@ -187,6 +187,110 @@ end end + context 'when SCC API suceeds for HYBRiD system' do + let(:product) do + FactoryBot.create(:product, :product_sles, :extension, :with_mirrored_repositories, :with_mirrored_extensions, :activated, system: system_hybrid) + end + let(:payload) do + { + identifier: product.identifier, + version: product.version, + arch: product.arch + } + end + 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(:scc_systems_activations_url) { 'https://scc.suse.com/connect/systems/activations' } + + before do + stub_request(:delete, scc_systems_products_url) + .to_return( + status: 200, + body: "{\"error\": \"Could not de-activate product \'#{product.friendly_name}\'\"}", + headers: {} + ) + stub_request(:get, scc_systems_activations_url).to_return(status: 200, body: body_active, headers: {}) + delete url, params: payload, headers: headers + end + + context 'when only one product was active' do + let(:body_active) do + [{ + id: 1, + regcode: '631dc51f', + name: 'Subscription 1', + type: 'FULL', + status: 'ACTIVE', + starts_at: 'null', + expires_at: DateTime.parse((Time.zone.today + 1).to_s), + system_limit: 6, + systems_count: 1, + service: { + product: { + id: system_hybrid.activations.first.product.id, + product_class: system_hybrid.activations.first.product.product_class + } + } + }].to_json + end + + it 'makes the hybrid system payg' do + updated_system = System.find_by(login: system_hybrid.login) + expect(updated_system.payg?).to eq(true) + end + end + + context 'when more activations are left' do + let(:body_active) do + [ + { + id: 1, + regcode: '631dc51f', + name: 'Subscription 1', + type: 'FULL', + status: 'ACTIVE', + starts_at: 'null', + expires_at: DateTime.parse((Time.zone.today + 1).to_s), + system_limit: 6, + systems_count: 1, + service: { + product: { + id: system_hybrid.activations.first.product.id, + product_class: system_hybrid.activations.first.product.product_class + } + } + }, { + id: 2, + regcode: '631dc51f', + name: 'Subscription 1', + type: 'FULL', + status: 'ACTIVE', + starts_at: 'null', + expires_at: DateTime.parse((Time.zone.today + 1).to_s), + system_limit: 6, + systems_count: 1, + service: { + product: { + id: '30', + product_class: '23' + } + } + } + ].to_json + end + + it 'keeps the system as hybrid' do + updated_system = System.find_by(login: system_hybrid.login) + expect(updated_system.hybrid?).to eq(true) + end + end + end + context 'when SCC API returns an error' do let(:product) do FactoryBot.create(:product, :product_sles, :extension, :with_mirrored_repositories, :with_mirrored_extensions, :activated, system: system_hybrid) From 0e1095ee9635a1fca8e0ada5ebd8f60932cc4635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Berm=C3=BAdez=20Vel=C3=A1zquez?= Date: Wed, 28 Aug 2024 09:06:35 +0100 Subject: [PATCH 2/9] Update comment wording Co-authored-by: Thomas Schmidt --- engines/scc_proxy/lib/scc_proxy/engine.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index 7a52c8ab0..c059f2440 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -405,8 +405,8 @@ def scc_deactivate_product # it is OK to remove it from SCC response = SccProxy.deactivate_product_scc(auth, @product, @system.system_token) handle_response(response) - # if the system does not have more non free products activated on SCC - # system should turn to hybrid + # if the system does not have more products activated on SCC + # switch it back to payg @system.payg! if no_more_activations scc_systems_activations elsif result[:message].downcase.include?('unexpected error') raise ActionController::TranslatedError.new(result[:message]) From 8284043115650973e54d4e67b6f1a07f718e4d3a Mon Sep 17 00:00:00 2001 From: Jesus Bermudez Velazquez Date: Wed, 28 Aug 2024 10:07:57 +0100 Subject: [PATCH 3/9] Rename method to a positive name --- engines/scc_proxy/lib/scc_proxy/engine.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index c059f2440..8e1847454 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -407,7 +407,7 @@ def scc_deactivate_product handle_response(response) # if the system does not have more products activated on SCC # switch it back to payg - @system.payg! if no_more_activations scc_systems_activations + @system.payg! unless system_has_paid_extension? scc_systems_activations elsif result[:message].downcase.include?('unexpected error') raise ActionController::TranslatedError.new(result[:message]) end @@ -433,13 +433,13 @@ def handle_response(response) end end - def no_more_activations(scc_systems_activations) + def system_has_paid_extension?(scc_systems_activations) active_products_classes = scc_systems_activations.map do |act| if act['status'].casecmp('active').zero? && act['service']['product']['product_class'] != @product.product_class act['service']['product']['product_class'] end end.flatten.compact - active_products_classes.empty? + active_products_classes.present? end end From cfccb5cc204bb115a531db74ba9113748c68170d Mon Sep 17 00:00:00 2001 From: Jesus Bermudez Velazquez Date: Wed, 28 Aug 2024 11:25:32 +0100 Subject: [PATCH 4/9] Remove method and use inline condition Remove one line method and move the check to the method call --- engines/scc_proxy/lib/scc_proxy/engine.rb | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index 8e1847454..a6713906a 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -407,7 +407,9 @@ def scc_deactivate_product handle_response(response) # if the system does not have more products activated on SCC # switch it back to payg - @system.payg! unless system_has_paid_extension? scc_systems_activations + # drop the just de-activated activation from the list to avoid another call to SCC + # and check if there is any product + @system.payg! if scc_systems_activations.reject! { |act| act['service']['product']['id'] == @product.id }.blank? elsif result[:message].downcase.include?('unexpected error') raise ActionController::TranslatedError.new(result[:message]) end @@ -432,15 +434,6 @@ def handle_response(response) raise ActionController::TranslatedError.new(error['error']) end end - - def system_has_paid_extension?(scc_systems_activations) - active_products_classes = scc_systems_activations.map do |act| - if act['status'].casecmp('active').zero? && act['service']['product']['product_class'] != @product.product_class - act['service']['product']['product_class'] - end - end.flatten.compact - active_products_classes.present? - end end Api::Connect::V3::Systems::SystemsController.class_eval do From 4b1421d7bbf09f9d78d5b002fadd93d6ccd9a40b Mon Sep 17 00:00:00 2001 From: Jesus Bermudez Velazquez Date: Wed, 28 Aug 2024 11:28:44 +0100 Subject: [PATCH 5/9] Fix linter --- engines/scc_proxy/lib/scc_proxy/engine.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index a6713906a..13789cccd 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -389,6 +389,7 @@ def deregister_hybrid(auth) protected + # rubocop:disable Metrics/PerceivedComplexity def scc_deactivate_product auth = request.headers['HTTP_AUTHORIZATION'] if @system.byos? && @product[:product_type] != 'base' @@ -416,6 +417,7 @@ def scc_deactivate_product end logger.info "Product '#{@product.friendly_name}' successfully deactivated from SCC" end + # rubocop:enable Metrics/PerceivedComplexity def find_hybrid_product_on_scc(headers) response = SccProxy.get_scc_activations(headers, @system.system_token, @system.proxy_byos_mode) From f16feb2cf883ada29207cce9c6690e942a3ccf31 Mon Sep 17 00:00:00 2001 From: Jesus Bermudez Velazquez Date: Wed, 28 Aug 2024 11:54:02 +0100 Subject: [PATCH 6/9] Refactor deactivate product of a hybrid system Move the exception handling to SccProxy's deactive_product_scc method Rename method for accuracy --- engines/scc_proxy/lib/scc_proxy/engine.rb | 36 ++++++++++------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index 13789cccd..5f30ed65a 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -136,7 +136,7 @@ def scc_activate_product(product, auth, params, mode) http.request(scc_request) end - def deactivate_product_scc(auth, product, params) + def deactivate_product_scc(auth, product, params, logger) uri = URI.parse(DEREGISTER_PRODUCT_URL) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true @@ -147,7 +147,14 @@ def deactivate_product_scc(auth, product, params) arch: product.arch, byos: true }.to_json - http.request(scc_request) + response = http.request(scc_request) + unless response.code_type == Net::HTTPOK + error = JSON.parse(response.body) + error['error'] = SccProxy.parse_error(error['error'], params[:token], params[:email]) if error['error'].include? 'json' + logger.info "Could not de-activate product '#{product.friendly_name}', error: #{error['error']} #{response.code}" + raise ActionController::TranslatedError.new(error['error']) + end + response end def deregister_system_scc(auth, system_token) @@ -393,24 +400,21 @@ def deregister_hybrid(auth) def scc_deactivate_product auth = request.headers['HTTP_AUTHORIZATION'] if @system.byos? && @product[:product_type] != 'base' - response = SccProxy.deactivate_product_scc(auth, @product, @system.system_token) - handle_response(response) + SccProxy.deactivate_product_scc(auth, @product, @system.system_token, logger) elsif @system.hybrid? && @product.extension? # check if product is on SCC and # if it is -> de-activate it - scc_systems_activations = find_hybrid_product_on_scc(request.headers) - result = SccProxy.product_class_access(scc_systems_activations, @product.product_class) + result = find_hybrid_activations_on_scc(request.headers) if result[:is_active] || (!result[:is_active] && result[:message].downcase.include?('expired')) # if product is active on SCC or # product subscription expired # it is OK to remove it from SCC - response = SccProxy.deactivate_product_scc(auth, @product, @system.system_token) - handle_response(response) + SccProxy.deactivate_product_scc(auth, @product, @system.system_token, logger) # if the system does not have more products activated on SCC # switch it back to payg # drop the just de-activated activation from the list to avoid another call to SCC # and check if there is any product - @system.payg! if scc_systems_activations.reject! { |act| act['service']['product']['id'] == @product.id }.blank? + @system.payg! if @scc_systems_activations.reject! { |act| act['service']['product']['id'] == @product.id }.blank? elsif result[:message].downcase.include?('unexpected error') raise ActionController::TranslatedError.new(result[:message]) end @@ -419,22 +423,14 @@ def scc_deactivate_product end # rubocop:enable Metrics/PerceivedComplexity - def find_hybrid_product_on_scc(headers) + def find_hybrid_activations_on_scc(headers) response = SccProxy.get_scc_activations(headers, @system.system_token, @system.proxy_byos_mode) unless response.code_type == Net::HTTPOK logger.info "Could not get the system (#{@system.login}) activations, error: #{response.message} #{response.code}" raise ActionController::TranslatedError.new(response.body) end - JSON.parse(response.body) - end - - def handle_response(response) - unless response.code_type == Net::HTTPOK - error = JSON.parse(response.body) - error['error'] = SccProxy.parse_error(error['error'], params[:token], params[:email]) if error['error'].include? 'json' - logger.info "Could not de-activate product '#{@product.friendly_name}', error: #{error['error']} #{response.code}" - raise ActionController::TranslatedError.new(error['error']) - end + @scc_systems_activations = JSON.parse(response.body) + SccProxy.product_class_access(@scc_systems_activations, @product.product_class) end end From d28f64be2290476a305c8d5b71f2980d7dbce5d5 Mon Sep 17 00:00:00 2001 From: Jesus Bermudez Velazquez Date: Wed, 28 Aug 2024 11:57:30 +0100 Subject: [PATCH 7/9] No need to alter the same array --- engines/scc_proxy/lib/scc_proxy/engine.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index 5f30ed65a..2c7bb1b54 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -414,7 +414,7 @@ def scc_deactivate_product # switch it back to payg # drop the just de-activated activation from the list to avoid another call to SCC # and check if there is any product - @system.payg! if @scc_systems_activations.reject! { |act| act['service']['product']['id'] == @product.id }.blank? + @system.payg! if @scc_systems_activations.reject { |act| act['service']['product']['id'] == @product.id }.blank? elsif result[:message].downcase.include?('unexpected error') raise ActionController::TranslatedError.new(result[:message]) end From e4dc3f8a71952860cb889c5ce9bf97fab94df810 Mon Sep 17 00:00:00 2001 From: Jesus Bermudez Velazquez Date: Wed, 28 Aug 2024 13:28:59 +0100 Subject: [PATCH 8/9] Deregister system from SCC when switching to PAYG If a hybrid system deactivates a product from SCC and has no more products on SCC, the system becomes PAYG and, as such, it should be deregister from SCC --- engines/scc_proxy/lib/scc_proxy/engine.rb | 36 ++- .../v4/systems/products_controller_spec.rb | 259 +++--------------- 2 files changed, 60 insertions(+), 235 deletions(-) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index 2c7bb1b54..cc84ad2c5 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -396,7 +396,6 @@ def deregister_hybrid(auth) protected - # rubocop:disable Metrics/PerceivedComplexity def scc_deactivate_product auth = request.headers['HTTP_AUTHORIZATION'] if @system.byos? && @product[:product_type] != 'base' @@ -404,24 +403,16 @@ def scc_deactivate_product elsif @system.hybrid? && @product.extension? # check if product is on SCC and # if it is -> de-activate it - result = find_hybrid_activations_on_scc(request.headers) - if result[:is_active] || (!result[:is_active] && result[:message].downcase.include?('expired')) - # if product is active on SCC or - # product subscription expired + scc_systems_activations = find_hybrid_activations_on_scc(request.headers) + if scc_systems_activations.map { |act| act['service']['product']['id'] == @product.id }.present? + # if product is found on SCC, regardless of the state # it is OK to remove it from SCC SccProxy.deactivate_product_scc(auth, @product, @system.system_token, logger) - # if the system does not have more products activated on SCC - # switch it back to payg - # drop the just de-activated activation from the list to avoid another call to SCC - # and check if there is any product - @system.payg! if @scc_systems_activations.reject { |act| act['service']['product']['id'] == @product.id }.blank? - elsif result[:message].downcase.include?('unexpected error') - raise ActionController::TranslatedError.new(result[:message]) + handle_system_mode(auth) if scc_systems_activations.reject { |act| act['service']['product']['id'] == @product.id }.blank? end end logger.info "Product '#{@product.friendly_name}' successfully deactivated from SCC" end - # rubocop:enable Metrics/PerceivedComplexity def find_hybrid_activations_on_scc(headers) response = SccProxy.get_scc_activations(headers, @system.system_token, @system.proxy_byos_mode) @@ -429,8 +420,23 @@ def find_hybrid_activations_on_scc(headers) logger.info "Could not get the system (#{@system.login}) activations, error: #{response.message} #{response.code}" raise ActionController::TranslatedError.new(response.body) end - @scc_systems_activations = JSON.parse(response.body) - SccProxy.product_class_access(@scc_systems_activations, @product.product_class) + JSON.parse(response.body) + end + + def handle_system_mode(auth) + # if the system does not have more products activated on SCC + # switch it back to payg + # drop the just de-activated activation from the list to avoid another call to SCC + # and check if there is any product + response = SccProxy.deregister_system_scc(auth, @system.system_token) + unless response.code_type == Net::HTTPNoContent + error = JSON.parse(response.body) + logger.info "Could not de-activate system #{@system.login}, error: #{error['error']} #{response.code}" + error['error'] = SccProxy.parse_error(error['error'], params[:token], params[:email]) if error['error'].include? 'json' + raise ActionController::TranslatedError.new(error['error']) + end + logger.info 'System successfully deregistered from SCC' + @system.payg! end end diff --git a/engines/scc_proxy/spec/requests/api/connect/v4/systems/products_controller_spec.rb b/engines/scc_proxy/spec/requests/api/connect/v4/systems/products_controller_spec.rb index 586921c26..8c1801c33 100644 --- a/engines/scc_proxy/spec/requests/api/connect/v4/systems/products_controller_spec.rb +++ b/engines/scc_proxy/spec/requests/api/connect/v4/systems/products_controller_spec.rb @@ -187,7 +187,7 @@ end end - context 'when SCC API suceeds for HYBRiD system' do + context 'when SCC API suceeds for HYBRID system' do let(:product) do FactoryBot.create(:product, :product_sles, :extension, :with_mirrored_repositories, :with_mirrored_extensions, :activated, system: system_hybrid) end @@ -204,8 +204,8 @@ base_url: URI::HTTP.build({ scheme: response.request.scheme, host: response.request.host }).to_s ).to_json end - let(:scc_systems_activations_url) { 'https://scc.suse.com/connect/systems/activations' } + let(:scc_systems_url) { 'https://scc.suse.com/connect/systems' } before do stub_request(:delete, scc_systems_products_url) @@ -215,7 +215,6 @@ headers: {} ) stub_request(:get, scc_systems_activations_url).to_return(status: 200, body: body_active, headers: {}) - delete url, params: payload, headers: headers end context 'when only one product was active' do @@ -239,9 +238,38 @@ }].to_json end - it 'makes the hybrid system payg' do - updated_system = System.find_by(login: system_hybrid.login) - expect(updated_system.payg?).to eq(true) + context 'when deactivating the system succeeds' do + before do + stub_request(:delete, scc_systems_url).to_return(status: 204, body: '', headers: {}) + delete url, params: payload, headers: headers + end + + it 'makes the hybrid system payg' do + updated_system = System.find_by(login: system_hybrid.login) + expect(updated_system.payg?).to eq(true) + end + end + + context 'when deactivating the system fails' do + before do + allow(Rails.logger).to receive(:info) + stub_request(:delete, scc_systems_url).to_return( + status: 422, + body: '{"error": "Oh oh, something went wrong"}', + headers: {} + ) + delete url, params: payload, headers: headers + end + + it 'makes the hybrid system payg' do + expect(Rails.logger).to( + have_received(:info).with( + "Could not de-activate system #{system_hybrid.login}, error: Oh oh, something went wrong 422" + ).once + ) + data = JSON.parse(response.body) + expect(data['error']).to eq('Oh oh, something went wrong') + end end end @@ -284,226 +312,17 @@ ].to_json end + before do + stub_request(:delete, scc_systems_url).to_return(status: 204, body: '', headers: {}) + delete url, params: payload, headers: headers + end + it 'keeps the system as hybrid' do updated_system = System.find_by(login: system_hybrid.login) expect(updated_system.hybrid?).to eq(true) end end end - - context 'when SCC API returns an error' do - let(:product) do - FactoryBot.create(:product, :product_sles, :extension, :with_mirrored_repositories, :with_mirrored_extensions, :activated, system: system_hybrid) - end - let(:payload) do - { - identifier: product.identifier, - version: product.version, - arch: product.arch - } - end - 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(:body_active) do - { - id: 1, - regcode: '631dc51f', - name: 'Subscription 1', - type: 'FULL', - status: 'ACTIVE', - starts_at: 'null', - expires_at: DateTime.parse((Time.zone.today + 1).to_s), - system_limit: 6, - systems_count: 1, - service: { - product: { - id: system_hybrid.activations.first.product.id, - product_class: system_hybrid.activations.first.product.product_class - } - } - } - end - let(:scc_systems_activations_url) { 'https://scc.suse.com/connect/systems/activations' } - - before do - stub_request(:delete, scc_systems_products_url) - .to_return( - status: 422, - body: "{\"error\": \"Could not de-activate product \'#{product.friendly_name}\'\"}", - headers: {} - ) - stub_request(:get, scc_systems_activations_url).to_return(status: 200, body: [body_active].to_json, headers: {}) - delete url, params: payload, headers: headers - end - - it 'reports an error' do - data = JSON.parse(response.body) - expect(data['error']).to eq('Could not de-activate product \'SUSE Linux Enterprise Server 15 SP3 x86_64\'') - end - end - - context 'when product is expired' do - let(:product) do - FactoryBot.create(:product, :product_sles, :extension, :with_mirrored_repositories, :with_mirrored_extensions, :activated, system: system_hybrid) - end - let(:payload) do - { - identifier: product.identifier, - version: product.version, - arch: product.arch - } - end - 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(:body_expired) do - { - id: 1, - regcode: '631dc51f', - name: 'Subscription 1', - type: 'FULL', - status: 'EXPIRED', - starts_at: 'null', - expires_at: DateTime.parse((Time.zone.today - 1).to_s), - system_limit: 6, - systems_count: 1, - service: { - product: { - id: system_hybrid.activations.first.product.id, - product_class: system_hybrid.activations.first.product.product_class - } - } - } - end - let(:scc_systems_activations_url) { 'https://scc.suse.com/connect/systems/activations' } - - before do - stub_request(:delete, scc_systems_products_url) - .to_return( - status: 422, - body: "{\"error\": \"Could not de-activate product \'#{product.friendly_name}\'\"}", - headers: {} - ) - stub_request(:get, scc_systems_activations_url).to_return(status: 200, body: [body_expired].to_json, headers: {}) - delete url, params: payload, headers: headers - end - - it 'reports an error' do - data = JSON.parse(response.body) - expect(data['error']).to eq('Could not de-activate product \'SUSE Linux Enterprise Server 15 SP3 x86_64\'') - end - end - - context 'when product is not active' do - let(:product) do - FactoryBot.create(:product, :product_sles, :extension, :with_mirrored_repositories, :with_mirrored_extensions, :activated, system: system_hybrid) - end - let(:payload) do - { - identifier: product.identifier, - version: product.version, - arch: product.arch - } - end - 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(:body_not_activated) do - { - id: 1, - regcode: '631dc51f', - name: 'Subscription 1', - type: 'FULL', - status: 'ACTIVE', - starts_at: 'null', - expires_at: DateTime.parse((Time.zone.today - 1).to_s), - system_limit: 6, - systems_count: 1, - service: { - product: { - id: 1, - product_class: product.product_class + 'FOO' - } - } - } - end - let(:scc_systems_activations_url) { 'https://scc.suse.com/connect/systems/activations' } - - before do - stub_request(:get, scc_systems_activations_url).to_return(status: 200, body: [body_not_activated].to_json, headers: {}) - delete url, params: payload, headers: headers - end - - it 'reports an error' do - data = JSON.parse(response.body) - expect(data['error']).to eq(nil) - end - end - - context 'when product has unknown status' do - let(:product) do - FactoryBot.create(:product, :product_sles, :extension, :with_mirrored_repositories, :with_mirrored_extensions, :activated, system: system_hybrid) - end - let(:payload) do - { - identifier: product.identifier, - version: product.version, - arch: product.arch - } - end - 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(:body_unknown_status) do - { - id: 1, - regcode: '631dc51f', - name: 'Subscription 1', - type: 'FULL', - status: 'FOO', - starts_at: 'null', - expires_at: DateTime.parse((Time.zone.today - 1).to_s), - system_limit: 6, - systems_count: 1, - service: { - product: { - id: system_hybrid.activations.first.product.id, - product_class: system_hybrid.activations.first.product.product_class + 'FOO' - } - } - } - end - let(:scc_systems_activations_url) { 'https://scc.suse.com/connect/systems/activations' } - - before do - stub_request(:delete, scc_systems_products_url) - .to_return( - status: 422, - body: "{\"error\": \"Could not de-activate product \'#{product.friendly_name}\'\"}", - headers: {} - ) - stub_request(:get, scc_systems_activations_url).to_return(status: 200, body: [body_unknown_status].to_json, headers: {}) - delete url, params: payload, headers: headers - end - - it 'reports an error' do - data = JSON.parse(response.body) - expect(data['error']).to eq('Unexpected error when checking product subscription.') - end - end end context 'an activated base module with right credentials' do From 1c2929c4dbcd84f9f2efa7ea7108d4d5cd89bcb8 Mon Sep 17 00:00:00 2001 From: Jesus Bermudez Velazquez Date: Wed, 28 Aug 2024 14:55:50 +0100 Subject: [PATCH 9/9] rename method --- engines/scc_proxy/lib/scc_proxy/engine.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/scc_proxy/lib/scc_proxy/engine.rb b/engines/scc_proxy/lib/scc_proxy/engine.rb index cc84ad2c5..f551e4500 100644 --- a/engines/scc_proxy/lib/scc_proxy/engine.rb +++ b/engines/scc_proxy/lib/scc_proxy/engine.rb @@ -408,7 +408,7 @@ def scc_deactivate_product # if product is found on SCC, regardless of the state # it is OK to remove it from SCC SccProxy.deactivate_product_scc(auth, @product, @system.system_token, logger) - handle_system_mode(auth) if scc_systems_activations.reject { |act| act['service']['product']['id'] == @product.id }.blank? + make_system_payg(auth) if scc_systems_activations.reject { |act| act['service']['product']['id'] == @product.id }.blank? end end logger.info "Product '#{@product.friendly_name}' successfully deactivated from SCC" @@ -423,7 +423,7 @@ def find_hybrid_activations_on_scc(headers) JSON.parse(response.body) end - def handle_system_mode(auth) + def make_system_payg(auth) # if the system does not have more products activated on SCC # switch it back to payg # drop the just de-activated activation from the list to avoid another call to SCC