foreman_scc_manager 1.8.2 → 1.8.7
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 -11
- data/app/lib/actions/scc_manager/sync_repositories.rb +9 -11
- data/app/lib/scc_manager.rb +2 -2
- data/app/models/scc_account.rb +70 -11
- 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 +17 -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: 843165a6092fcb04bf69d13131ae44acb02478ce347084c160a8f61891770eba
|
4
|
+
data.tar.gz: 892025747b9572a4b31d25f4c96ab28ea9af0099ef3302fe8c7aec07935b588b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cb42eeb656e4a0cca5c93d7c83e0fed14fa73a9b0e7f2ad0ddcb07b007156405f0e91d968e4eb38aafd6376551f334340bda0a4ff9d632d13d4818766e7eb75
|
7
|
+
data.tar.gz: 700546d7abfdc1ff7fc12f452c69bb6ca8869c41b63ae4e37fef99541dc229bf2287de3435ecd8c09dee32cb79465b8c896af09c78b4d0d498209e35c8a347cf
|
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,20 +13,19 @@ module Actions
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def run
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
output[:status] = 'FAILURE'
|
25
|
-
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
|
26
24
|
end
|
27
25
|
|
28
26
|
def finalize
|
29
|
-
|
27
|
+
# this is only executed if 'run' succeeds
|
28
|
+
SccAccount.find(input.fetch(:id)).update_scc_products(output.fetch(:data))
|
30
29
|
end
|
31
30
|
|
32
31
|
def rescue_strategy
|
@@ -12,20 +12,18 @@ module Actions
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def run
|
15
|
-
output[:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
rescue StandardError
|
23
|
-
output[:status] = 'FAILURE'
|
24
|
-
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
|
25
22
|
end
|
26
23
|
|
27
24
|
def finalize
|
28
|
-
|
25
|
+
# this is only executed if 'run' succeeds
|
26
|
+
SccAccount.find(input[:scc_account][:id]).update_scc_repositories(output[:data])
|
29
27
|
end
|
30
28
|
|
31
29
|
def rescue_strategy
|
data/app/lib/scc_manager.rb
CHANGED
@@ -8,8 +8,8 @@ module SccManager
|
|
8
8
|
uri.scheme = URI.parse(proxy_config[:host]).scheme
|
9
9
|
uri.host = URI.parse(proxy_config[:host]).host
|
10
10
|
uri.port = proxy_config[:port].try(:to_s)
|
11
|
-
uri.user = proxy_config[:user]
|
12
|
-
uri.password = proxy_config[:password].
|
11
|
+
uri.user = proxy_config[:user]
|
12
|
+
uri.password = proxy_config[:password] if uri.user.present?
|
13
13
|
|
14
14
|
RestClient.proxy = uri.to_s
|
15
15
|
end
|
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
|
@@ -166,38 +169,53 @@ class SccAccount < ApplicationRecord
|
|
166
169
|
def test_connection
|
167
170
|
get_scc_data('/connect/organizations/subscriptions')
|
168
171
|
true
|
169
|
-
rescue StandardError
|
172
|
+
rescue StandardError => e
|
173
|
+
::Foreman::Logging.logger('foreman_scc_manager').warn "Error occurred while testing SCC-Connection to Account #{self}: #{e}"
|
170
174
|
false
|
171
175
|
end
|
172
176
|
|
173
177
|
def update_scc_repositories(upstream_repositories)
|
174
178
|
upstream_repo_ids = []
|
179
|
+
# initially invalidate all repositories and validate them during update
|
180
|
+
invalidated_repos = invalidate_subscription_status(scc_repositories)
|
175
181
|
# import repositories
|
176
182
|
upstream_repositories.each do |ur|
|
177
183
|
cached_repository = scc_repositories.find_or_initialize_by(scc_id: ur['id'])
|
178
|
-
cached_repository.name = ur['name']
|
179
184
|
cached_repository.distro_target = ur['distro_target']
|
180
185
|
cached_repository.description = ur['description']
|
181
186
|
cached_repository.url, cached_repository.token = ur['url'].split('?')
|
182
187
|
cached_repository.enabled = ur['enabled']
|
183
188
|
cached_repository.autorefresh = ur['autorefresh']
|
184
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
|
185
193
|
cached_repository.save!
|
186
194
|
upstream_repo_ids << ur['id']
|
195
|
+
# set invalidated record to true, if exists
|
196
|
+
invalidated_repos = revalidate_subscription_status(invalidated_repos, ur[id])
|
187
197
|
end
|
188
|
-
logger.debug "Found #{upstream_repo_ids.length} repositories"
|
189
|
-
|
198
|
+
::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_repo_ids.length} repositories"
|
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
|
190
207
|
to_delete = scc_repositories.where.not(scc_id: upstream_repo_ids)
|
191
|
-
logger.debug "Deleting #{to_delete.count} old repositories"
|
208
|
+
::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old repositories"
|
192
209
|
to_delete.destroy_all
|
193
210
|
end
|
194
211
|
|
195
212
|
def update_scc_products(upstream_products)
|
196
213
|
upstream_product_ids = []
|
214
|
+
# initially invalidate all products and validate them during update
|
215
|
+
invalidated_products = invalidate_subscription_status(scc_products)
|
197
216
|
# import products
|
198
217
|
upstream_products.each do |up|
|
199
218
|
cached_product = scc_products.find_or_initialize_by(scc_id: up['id'])
|
200
|
-
cached_product.name = up['name']
|
201
219
|
cached_product.version = up['version']
|
202
220
|
cached_product.arch = up['arch']
|
203
221
|
cached_product.description = up['description']
|
@@ -205,13 +223,26 @@ class SccAccount < ApplicationRecord
|
|
205
223
|
cached_product.product_type = up['product_type']
|
206
224
|
cached_product.scc_repositories =
|
207
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
|
208
230
|
cached_product.save!
|
209
231
|
upstream_product_ids << up['id']
|
232
|
+
# set invalidated record to true, if exists
|
233
|
+
invalidated_products = revalidate_subscription_status(invalidated_products, up['id'])
|
210
234
|
end
|
211
|
-
logger.debug "Found #{upstream_product_ids.length} products"
|
212
|
-
|
213
|
-
|
214
|
-
|
235
|
+
::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_product_ids.length} products"
|
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)
|
245
|
+
::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old products"
|
215
246
|
to_delete.destroy_all
|
216
247
|
# rewire product to product relationships
|
217
248
|
upstream_products.each do |up|
|
@@ -219,8 +250,36 @@ class SccAccount < ApplicationRecord
|
|
219
250
|
begin
|
220
251
|
scc_products.find_by!(scc_id: up['id']).update!(scc_extensions: extensions)
|
221
252
|
rescue ActiveRecord::RecordNotFound
|
222
|
-
logger.info "Failed to find parent scc_product '#{up['name']}'."
|
253
|
+
::Foreman::Logging.logger('foreman_scc_manager').info "Failed to find parent scc_product '#{up['name']}'."
|
254
|
+
end
|
255
|
+
end
|
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
|
223
281
|
end
|
224
282
|
end
|
283
|
+
items_to_invalidate
|
225
284
|
end
|
226
285
|
end
|