foreman_scc_manager 1.8.3 → 1.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/app/controllers/api/v2/scc_accounts_controller.rb +9 -7
- data/app/controllers/scc_accounts_controller.rb +30 -4
- data/app/lib/actions/scc_manager/subscribe_product.rb +26 -13
- data/app/lib/actions/scc_manager/sync.rb +5 -5
- data/app/lib/actions/scc_manager/sync_products.rb +10 -13
- data/app/lib/actions/scc_manager/sync_repositories.rb +9 -13
- data/app/models/scc_account.rb +63 -5
- data/app/models/scc_product.rb +20 -2
- data/app/models/scc_repository.rb +11 -9
- data/app/views/scc_accounts/_form.html.erb +6 -0
- data/app/views/scc_accounts/index.html.erb +4 -3
- data/app/views/scc_accounts/show.html.erb +13 -4
- data/db/migrate/20200520281300_fix_scc_permissions.rb +22 -0
- data/db/migrate/20201119084201_add_gpg_key_to_scc_account.rb +6 -0
- data/db/migrate/20210205082733_add_subscription_valid_to_scc_products_and_repos.rb +6 -0
- data/db/migrate/20210210104407_add_root_repository_id_to_scc_repository.rb +6 -0
- data/db/migrate/20210224095050_connect_katello_root_repository_to_scc_repository.rb +28 -0
- data/lib/foreman_scc_manager/engine.rb +36 -25
- data/lib/foreman_scc_manager/version.rb +1 -1
- data/lib/tasks/test.rake +1 -1
- data/locale/de/LC_MESSAGES/foreman_scc_manager.mo +0 -0
- data/locale/de/foreman_scc_manager.edit.po +574 -0
- data/locale/de/foreman_scc_manager.po +40 -21
- data/locale/de/foreman_scc_manager.po.time_stamp +0 -0
- data/locale/en/foreman_scc_manager.edit.po +566 -0
- data/locale/en/foreman_scc_manager.po +21 -3
- data/locale/en/foreman_scc_manager.po.time_stamp +0 -0
- data/locale/foreman_scc_manager.pot +65 -38
- data/test/controllers/api/v2/scc_accounts_test.rb +9 -3
- data/test/controllers/scc_accounts_controller_test.rb +104 -0
- data/test/controllers/scc_accounts_controller_test2.rb +51 -0
- data/test/fixtures/models/scc_extendings.yml +6 -0
- data/test/fixtures/models/scc_products.yml +30 -2
- data/test/fixtures/models/scc_repositories.yml +29 -0
- data/test/models/scc_account_test.rb +70 -0
- data/test/models/scc_product_test.rb +69 -1
- data/test/support/fixtures_support.rb +3 -2
- data/test/test_controller_helper.rb +15 -0
- data/test/test_plugin_helper.rb +9 -0
- metadata +33 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d51eed6c2336237f44aa0fad512060a43f4bc0dae6fd9a93daa2baa555f915a
|
4
|
+
data.tar.gz: 876ebdd4e76443deec6016c657b44ddcb1e60dcc2c8a81631e5f87cccafcc9b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef379e703604fc444d312969f4dd389c952b03dc3f3d5ba98d95989941c9b397b7879bef97d309ae54270f70ffb5b1ef50ee1ba214571800dc82f2ea7d301bd7
|
7
|
+
data.tar.gz: 70c8ddeef5a5ad620dfb6fe1ed3b2296e56cef24be9fc3b07223bc2978b5fb0f116d996bddea4e0bc50db1accef6a82ed263183d13fad7d23a56a9c15da077fc
|
data/README.md
CHANGED
@@ -13,6 +13,8 @@ for how to install Foreman plugins
|
|
13
13
|
|
14
14
|
| Foreman Version | Katello Version | Plugin Version |
|
15
15
|
| --------------- | --------------- | -------------- |
|
16
|
+
| 2.1 | 3.16 | ~> 1.8.5 |
|
17
|
+
| 2.0 | 3.16 | ~> 1.8.4 |
|
16
18
|
| 1.24 | 3.14 | ~> 1.8.0 |
|
17
19
|
| 1.22 | 3.12 | ~> 1.7.0 |
|
18
20
|
| 1.21 | 3.10 | ~> 1.6.0 |
|
@@ -23,6 +25,9 @@ for how to install Foreman plugins
|
|
23
25
|
| 1.16 | 3.5 | <= 1.3.0 |
|
24
26
|
| 1.15 | 3.4 | ~> 1.1.0 |
|
25
27
|
|
28
|
+
## Documentation
|
29
|
+
The plugin documentation can be found at https://docs.orcharhino.com/sources/management_ui/the_content_menu/suse_subscriptions.html.
|
30
|
+
|
26
31
|
## Contributing
|
27
32
|
|
28
33
|
Fork and send a Pull Request. Thanks!
|
@@ -18,7 +18,7 @@ module Api
|
|
18
18
|
def index
|
19
19
|
scope = resource_scope
|
20
20
|
scope = scope.where(:organization => params[:organization_id]) if params[:organization_id].present?
|
21
|
-
@scc_accounts = scope.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
|
21
|
+
@scc_accounts = scope.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page], :per_page => params[:per_page])
|
22
22
|
end
|
23
23
|
|
24
24
|
api :GET, '/scc_accounts/:id/', N_('Show scc_account')
|
@@ -34,7 +34,8 @@ module Api
|
|
34
34
|
param :password, String, :required => true, :desc => N_('Password of scc_account')
|
35
35
|
param :base_url, String, :required => false, :desc => N_('URL of SUSE for scc_account')
|
36
36
|
param :interval, ['never', 'daily', 'weekly', 'monthy'], :desc => N_('Interval for syncing scc_account')
|
37
|
-
param :sync_date, String, :desc => N_('
|
37
|
+
param :sync_date, String, :desc => N_('Date and time relative to which the sync interval is run')
|
38
|
+
param :katello_gpg_key_id, :identifier, :required => false, :desc => N_('Associated GPG key of scc_account')
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
@@ -79,9 +80,9 @@ module Api
|
|
79
80
|
end
|
80
81
|
respond_to do |format|
|
81
82
|
if @scc_account.test_connection
|
82
|
-
format.json { render json: '
|
83
|
+
format.json { render json: { 'success' => true }.to_json, status: :ok }
|
83
84
|
else
|
84
|
-
format.json { render json: '
|
85
|
+
format.json { render json: { 'success' => false, 'error' => 'Test failed. Check your credentials.' }.to_json, status: :not_found }
|
85
86
|
end
|
86
87
|
end
|
87
88
|
end
|
@@ -102,7 +103,7 @@ module Api
|
|
102
103
|
|
103
104
|
api :PUT, '/scc_accounts/:id/bulk_subscribe/', N_('Bulk subscription of scc_products for scc_account')
|
104
105
|
param :id, :identifier_dottable, :required => true
|
105
|
-
param :scc_subscribe_product_ids, Array
|
106
|
+
param :scc_subscribe_product_ids, Array, :required => true
|
106
107
|
def bulk_subscribe
|
107
108
|
scc_products_to_subscribe = @scc_account.scc_products.where(:id => params[:scc_subscribe_product_ids])
|
108
109
|
respond_to do |format|
|
@@ -112,7 +113,7 @@ module Api
|
|
112
113
|
scc_products_to_subscribe)
|
113
114
|
format.json { render json: subscribe_task.to_json, status: :ok }
|
114
115
|
else
|
115
|
-
format.json { render json: 'No Product selected'
|
116
|
+
format.json { render json: { error: 'No Product selected' }, status: :expectation_failed }
|
116
117
|
end
|
117
118
|
end
|
118
119
|
rescue ::Foreman::Exception => e
|
@@ -132,7 +133,8 @@ module Api
|
|
132
133
|
:base_url,
|
133
134
|
:interval,
|
134
135
|
:sync_date,
|
135
|
-
:organization_id
|
136
|
+
:organization_id,
|
137
|
+
:katello_gpg_key_id
|
136
138
|
)
|
137
139
|
end
|
138
140
|
|
@@ -1,12 +1,19 @@
|
|
1
1
|
class SccAccountsController < ApplicationController
|
2
|
+
helper_method :scc_filtered_products
|
2
3
|
before_action :find_organization
|
3
4
|
before_action :find_resource, only: %i[show edit update destroy sync bulk_subscribe]
|
5
|
+
before_action :find_available_gpg_keys, only: %i[new edit]
|
4
6
|
include Foreman::Controller::AutoCompleteSearch
|
5
7
|
|
6
8
|
# GET /scc_accounts
|
7
9
|
def index
|
8
|
-
@scc_accounts = resource_base.
|
9
|
-
.
|
10
|
+
@scc_accounts = resource_base.where(organization: @organization)
|
11
|
+
.search_for(params[:search], order: params[:order])
|
12
|
+
.paginate(:page => params[:page], :per_page => params[:per_page])
|
13
|
+
# overwrite the product list with filtered products that do not include products with empty repositories
|
14
|
+
@scc_accounts.each do |scc_account|
|
15
|
+
scc_account.scc_products_with_repos_count = scc_account.scc_products.only_products_with_repos.count
|
16
|
+
end
|
10
17
|
end
|
11
18
|
|
12
19
|
# GET /scc_accounts/new
|
@@ -92,6 +99,11 @@ class SccAccountsController < ApplicationController
|
|
92
99
|
|
93
100
|
private
|
94
101
|
|
102
|
+
def find_available_gpg_keys
|
103
|
+
@scc_account ? org = @scc_account.organization : org = @organization
|
104
|
+
@selectable_gpg_keys = ::Katello::GpgKey.where(organization: org).collect { |p| [p.name, p.id] }.unshift ['None', nil]
|
105
|
+
end
|
106
|
+
|
95
107
|
def find_organization
|
96
108
|
@organization = Organization.current
|
97
109
|
redirect_to '/select_organization?toState=' + request.path unless @organization
|
@@ -108,7 +120,8 @@ class SccAccountsController < ApplicationController
|
|
108
120
|
:base_url,
|
109
121
|
:interval,
|
110
122
|
:sync_date,
|
111
|
-
:organization_id
|
123
|
+
:organization_id,
|
124
|
+
:katello_gpg_key_id
|
112
125
|
)
|
113
126
|
end
|
114
127
|
|
@@ -121,9 +134,22 @@ class SccAccountsController < ApplicationController
|
|
121
134
|
when 'sync', 'test_connection'
|
122
135
|
:sync
|
123
136
|
when 'bulk_subscribe'
|
124
|
-
:
|
137
|
+
:use
|
125
138
|
else
|
126
139
|
super
|
127
140
|
end
|
128
141
|
end
|
142
|
+
|
143
|
+
# Function filters a product list and removes all products without valid repositories
|
144
|
+
# The .order call is necessary to apply the ordering to repository that have already been loaded from the database.
|
145
|
+
# Input parameters:
|
146
|
+
# product_list: list of SccProduct
|
147
|
+
# product_type: return only base products if type is set (default), else all
|
148
|
+
def scc_filtered_products(product_list, product_type = 'base')
|
149
|
+
if product_type == 'base'
|
150
|
+
product_list.only_products_with_repos.where(product_type: 'base').order(:friendly_name)
|
151
|
+
else
|
152
|
+
product_list.only_products_with_repos.order(:friendly_name)
|
153
|
+
end
|
154
|
+
end
|
129
155
|
end
|
@@ -8,27 +8,38 @@ module Actions
|
|
8
8
|
.info("Initiating subscription for SccProduct '#{scc_product.friendly_name}'.")
|
9
9
|
sequence do
|
10
10
|
product_create_action = plan_action(CreateProduct,
|
11
|
-
product_name
|
12
|
-
product_description
|
13
|
-
organization_id
|
11
|
+
:product_name => scc_product.pretty_name,
|
12
|
+
:product_description => scc_product.pretty_description,
|
13
|
+
:organization_id => scc_product.organization.id,
|
14
|
+
:gpg_key => scc_product.scc_account.katello_gpg_key_id)
|
15
|
+
katello_repos = {}
|
14
16
|
scc_product.scc_repositories.each do |repo|
|
15
|
-
uniq_name = scc_product.uniq_name + ' ' + repo.description
|
16
17
|
arch = scc_product.arch || 'noarch'
|
17
|
-
plan_action(CreateRepository,
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
repo_create_action = plan_action(CreateRepository,
|
19
|
+
:product_id => product_create_action.output[:product_id],
|
20
|
+
:uniq_name => repo.uniq_name(scc_product),
|
21
|
+
:pretty_repo_name => repo.pretty_name,
|
22
|
+
:url => repo.full_url,
|
23
|
+
:arch => arch)
|
24
|
+
katello_repos[repo.id] = repo_create_action.output[:katello_root_repository_id]
|
22
25
|
end
|
26
|
+
# connect action to resource (=> make parameters accessable in input)
|
23
27
|
action_subject(scc_product, product_id: product_create_action.output[:product_id])
|
28
|
+
input.update(katello_repos: katello_repos)
|
24
29
|
plan_self
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
33
|
def finalize
|
34
|
+
# connect Scc products and Katello products
|
29
35
|
scc_product = SccProduct.find(input[:scc_product][:id])
|
30
36
|
product = ::Katello::Product.find(input[:product_id])
|
31
37
|
scc_product.update!(product: product)
|
38
|
+
# extract Katello repo ids from input hash and store to database
|
39
|
+
input[:katello_repos].each do |scc_repo_id, katello_root_repository_id|
|
40
|
+
scc_repo = SccRepository.find(scc_repo_id)
|
41
|
+
scc_repo.update!(katello_root_repository_id: katello_root_repository_id)
|
42
|
+
end
|
32
43
|
end
|
33
44
|
|
34
45
|
def humanized_name
|
@@ -43,6 +54,7 @@ module Actions
|
|
43
54
|
def create_sub_plans
|
44
55
|
product = ::Katello::Product.new
|
45
56
|
product.name = input[:product_name]
|
57
|
+
product.gpg_key = ::Katello::GpgKey.find_by(id: input[:gpg_key], organization: input[:organization_id])
|
46
58
|
product.description = input[:product_description]
|
47
59
|
trigger(::Actions::Katello::Product::Create,
|
48
60
|
product,
|
@@ -58,12 +70,11 @@ module Actions
|
|
58
70
|
|
59
71
|
def create_sub_plans
|
60
72
|
product = ::Katello::Product.find(input[:product_id])
|
61
|
-
|
62
|
-
label = ::Katello::Util::Model.labelize(uniq_name)
|
73
|
+
label = ::Katello::Util::Model.labelize(input[:uniq_name])
|
63
74
|
unprotected = true
|
64
75
|
gpg_key = product.gpg_key
|
65
76
|
repo_param = { :label => label,
|
66
|
-
:name =>
|
77
|
+
:name => input[:pretty_repo_name],
|
67
78
|
:url => input[:url],
|
68
79
|
:content_type => 'yum',
|
69
80
|
:unprotected => unprotected,
|
@@ -73,7 +84,9 @@ module Actions
|
|
73
84
|
repository = product.add_repo(repo_param)
|
74
85
|
repository.mirror_on_sync = true
|
75
86
|
repository.verify_ssl_on_sync = true
|
76
|
-
trigger(::Actions::Katello::Repository::CreateRoot, repository)
|
87
|
+
trigger(::Actions::Katello::Repository::CreateRoot, repository).tap do
|
88
|
+
output[:katello_root_repository_id] = repository.id
|
89
|
+
end
|
77
90
|
end
|
78
91
|
end
|
79
92
|
end
|
@@ -1,21 +1,21 @@
|
|
1
1
|
module Actions
|
2
2
|
module SccManager
|
3
|
+
# for dynflow documentation see here: https://dynflow.github.io/documentation/
|
3
4
|
class Sync < Actions::EntryAction
|
4
5
|
def plan(scc_account)
|
5
6
|
::Foreman::Logging.logger('foreman_scc_manager')
|
6
7
|
.info("Initiating 'sync' for SccAccount '#{scc_account.name}'.")
|
7
8
|
action_subject(scc_account)
|
8
9
|
sequence do
|
9
|
-
|
10
|
-
|
11
|
-
plan_self
|
10
|
+
plan_action(::Actions::SccManager::SyncRepositories, scc_account)
|
11
|
+
plan_action(::Actions::SccManager::SyncProducts, scc_account)
|
12
|
+
plan_self
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
def finalize
|
17
|
+
# this is only executed if run actions of SyncRepositories and SyncProducts were successful
|
16
18
|
scc_account = SccAccount.find(input[:scc_account][:id])
|
17
|
-
raise 'Updating failed' unless input[:repo_status] == 'SUCCESS' && input[:prod_status] == 'SUCCESS'
|
18
|
-
|
19
19
|
scc_account.update! synced: Time.current
|
20
20
|
end
|
21
21
|
|
@@ -13,22 +13,19 @@ module Actions
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def run
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Products: #{e}"
|
25
|
-
output[:error] = e.to_s
|
26
|
-
output[:status] = 'FAILURE'
|
27
|
-
end
|
16
|
+
products = ::SccManager.get_scc_data(input.fetch(:base_url),
|
17
|
+
'/connect/organizations/products',
|
18
|
+
input.fetch(:login),
|
19
|
+
decrypt_field(input.fetch(:password)))
|
20
|
+
output[:data] = ::SccManager.sanitize_products(products).values
|
21
|
+
rescue StandardError => e
|
22
|
+
::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Products: #{e}"
|
23
|
+
error! e.to_s
|
28
24
|
end
|
29
25
|
|
30
26
|
def finalize
|
31
|
-
|
27
|
+
# this is only executed if 'run' succeeds
|
28
|
+
SccAccount.find(input.fetch(:id)).update_scc_products(output.fetch(:data))
|
32
29
|
end
|
33
30
|
|
34
31
|
def rescue_strategy
|
@@ -12,22 +12,18 @@ module Actions
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def run
|
15
|
-
output[:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
rescue StandardError => e
|
23
|
-
::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Repositories: #{e}"
|
24
|
-
output[:error] = e.to_s
|
25
|
-
output[:status] = 'FAILURE'
|
26
|
-
end
|
15
|
+
output[:data] = ::SccManager.get_scc_data(input[:base_url],
|
16
|
+
'/connect/organizations/repositories',
|
17
|
+
input[:login],
|
18
|
+
decrypt_field(input[:password]))
|
19
|
+
rescue StandardError => e
|
20
|
+
::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Repositories: #{e}"
|
21
|
+
error! e.to_s
|
27
22
|
end
|
28
23
|
|
29
24
|
def finalize
|
30
|
-
|
25
|
+
# this is only executed if 'run' succeeds
|
26
|
+
SccAccount.find(input[:scc_account][:id]).update_scc_repositories(output[:data])
|
31
27
|
end
|
32
28
|
|
33
29
|
def rescue_strategy
|
data/app/models/scc_account.rb
CHANGED
@@ -2,6 +2,9 @@ class SccAccount < ApplicationRecord
|
|
2
2
|
include Authorizable
|
3
3
|
include Encryptable
|
4
4
|
include ForemanTasks::Concerns::ActionSubject
|
5
|
+
|
6
|
+
attr_accessor :scc_products_with_repos_count
|
7
|
+
|
5
8
|
encrypts :password
|
6
9
|
|
7
10
|
NEVER = 'never'.freeze
|
@@ -173,21 +176,34 @@ class SccAccount < ApplicationRecord
|
|
173
176
|
|
174
177
|
def update_scc_repositories(upstream_repositories)
|
175
178
|
upstream_repo_ids = []
|
179
|
+
# initially invalidate all repositories and validate them during update
|
180
|
+
invalidated_repos = invalidate_subscription_status(scc_repositories)
|
176
181
|
# import repositories
|
177
182
|
upstream_repositories.each do |ur|
|
178
183
|
cached_repository = scc_repositories.find_or_initialize_by(scc_id: ur['id'])
|
179
|
-
cached_repository.name = ur['name']
|
180
184
|
cached_repository.distro_target = ur['distro_target']
|
181
185
|
cached_repository.description = ur['description']
|
182
186
|
cached_repository.url, cached_repository.token = ur['url'].split('?')
|
183
187
|
cached_repository.enabled = ur['enabled']
|
184
188
|
cached_repository.autorefresh = ur['autorefresh']
|
185
189
|
cached_repository.installer_updates = ur['installer_updates']
|
190
|
+
# should be called after all attributes are set in case of dependencies (currently: description)
|
191
|
+
cached_repository.name = cached_repository.pretty_name
|
192
|
+
cached_repository.subscription_valid = true
|
186
193
|
cached_repository.save!
|
187
194
|
upstream_repo_ids << ur['id']
|
195
|
+
# set invalidated record to true, if exists
|
196
|
+
invalidated_repos = revalidate_subscription_status(invalidated_repos, ur[id])
|
188
197
|
end
|
189
198
|
::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_repo_ids.length} repositories"
|
190
|
-
|
199
|
+
|
200
|
+
# all scc repos that are kept but not available upstream need to be marked invalid
|
201
|
+
# subscription_valid can be set to nil
|
202
|
+
to_invalidate = invalidated_repos.select { |ir| ir.katello_root_repository_id.present? && !ir.subscription_valid }
|
203
|
+
::Foreman::Logging.logger('foreman_scc_manager').debug "Invalidating #{to_invalidate.count} expired repositories"
|
204
|
+
invalidate_subscription_status(to_invalidate, true)
|
205
|
+
|
206
|
+
# delete repositories being removed upstream and that are not subscribed to
|
191
207
|
to_delete = scc_repositories.where.not(scc_id: upstream_repo_ids)
|
192
208
|
::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old repositories"
|
193
209
|
to_delete.destroy_all
|
@@ -195,10 +211,11 @@ class SccAccount < ApplicationRecord
|
|
195
211
|
|
196
212
|
def update_scc_products(upstream_products)
|
197
213
|
upstream_product_ids = []
|
214
|
+
# initially invalidate all products and validate them during update
|
215
|
+
invalidated_products = invalidate_subscription_status(scc_products)
|
198
216
|
# import products
|
199
217
|
upstream_products.each do |up|
|
200
218
|
cached_product = scc_products.find_or_initialize_by(scc_id: up['id'])
|
201
|
-
cached_product.name = up['name']
|
202
219
|
cached_product.version = up['version']
|
203
220
|
cached_product.arch = up['arch']
|
204
221
|
cached_product.description = up['description']
|
@@ -206,12 +223,25 @@ class SccAccount < ApplicationRecord
|
|
206
223
|
cached_product.product_type = up['product_type']
|
207
224
|
cached_product.scc_repositories =
|
208
225
|
scc_repositories.where(scc_id: up['repositories'].map { |repo| repo['id'] })
|
226
|
+
# name should be set after friendly_name because it depends on friendly_name
|
227
|
+
cached_product.name = cached_product.pretty_name
|
228
|
+
cached_product.description = cached_product.pretty_description
|
229
|
+
cached_product.subscription_valid = true
|
209
230
|
cached_product.save!
|
210
231
|
upstream_product_ids << up['id']
|
232
|
+
# set invalidated record to true, if exists
|
233
|
+
invalidated_products = revalidate_subscription_status(invalidated_products, up['id'])
|
211
234
|
end
|
212
235
|
::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_product_ids.length} products"
|
213
|
-
|
214
|
-
|
236
|
+
|
237
|
+
# all scc products that are kept but not available upstream need to be marked invalid
|
238
|
+
# subscription_valid can be set to nil
|
239
|
+
to_invalidate = invalidated_products.select { |ip| ip.product_id.present? && !ip.subscription_valid }
|
240
|
+
::Foreman::Logging.logger('foreman_scc_manager').debug "Invalidating #{to_invalidate.count} expired products"
|
241
|
+
invalidate_subscription_status(to_invalidate, true)
|
242
|
+
|
243
|
+
# delete products being removed upstream and that are not subscribed to
|
244
|
+
to_delete = scc_products.where.not(scc_id: upstream_product_ids).where(product_id: nil)
|
215
245
|
::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old products"
|
216
246
|
to_delete.destroy_all
|
217
247
|
# rewire product to product relationships
|
@@ -224,4 +254,32 @@ class SccAccount < ApplicationRecord
|
|
224
254
|
end
|
225
255
|
end
|
226
256
|
end
|
257
|
+
|
258
|
+
# validate the subscription status of a product/repo
|
259
|
+
# no saving to database
|
260
|
+
# params: elements: scc repos or products, Array or ActiveRecord_(*)
|
261
|
+
# scc_id: scc_id of the element that should be revalidated
|
262
|
+
# return: elements where for the element with scc_id subscription_valid is true
|
263
|
+
def revalidate_subscription_status(elements, scc_id)
|
264
|
+
return nil if elements.nil?
|
265
|
+
|
266
|
+
revalidate = elements.find { |e| e.scc_id == scc_id }
|
267
|
+
revalidate.subscription_valid = true unless revalidate.nil?
|
268
|
+
# return modified list
|
269
|
+
elements
|
270
|
+
end
|
271
|
+
|
272
|
+
# set all products/repos invalid
|
273
|
+
# params: items_to_invalidate: ActiveRecord_(*)
|
274
|
+
# save_record: store in database or not (default)
|
275
|
+
# return: ActiveRecord elements with invalidated subscription status
|
276
|
+
def invalidate_subscription_status(items_to_invalidate, save_record = false)
|
277
|
+
if items_to_invalidate.present?
|
278
|
+
items_to_invalidate.each do |inv|
|
279
|
+
inv.subscription_valid = false
|
280
|
+
inv.save! if save_record
|
281
|
+
end
|
282
|
+
end
|
283
|
+
items_to_invalidate
|
284
|
+
end
|
227
285
|
end
|